gpt4 book ai didi

python - OCaml 生成与 OCaml 运行时链接的共享对象

转载 作者:太空宇宙 更新时间:2023-11-04 08:36:05 25 4
gpt4 key购买 nike

我正在尝试使用 ctypes 中的 cdll 接口(interface)从 OCaml 库构建一个共享对象,我可以在 Python 下运行它.

有没有办法在 OCaml 工具链中引导某些东西来生成一个共享对象,并链接到它的依赖项?

我开始怀疑 OCaml 根本不支持我正在尝试做的事情。我想调用一个 OCaml 函数,然后让它产生某种结果并将控制权返回到调用它的地方。

这是我的 OCaml 库

(* foo.ml *)
let add x y = x + y

我在 OS X 上编译它时使用的命令。(使用 .so 而不是 .dylib 稍微违反了平台的命名约定,但是 ocamlopt 将只接受 .o.so 的扩展名。)

$ ocamlopt -output-obj -fPIC -o foo.so foo.ml

成功并生成 foo.so

这是我第一次尝试将共享对象加载到 python 程序(python 3.6)中。

# foo.py
import ctypes

lib = ctypes.cdll.LoadLibrary('./foo.so')

print("Loaded")

运行时出现如下错误

节选:

self._handle = _dlopen(self._name, mode)
OSError: dlopen(./foo.so, 6): Symbol not found: _caml_code_area_end

完整错误:

Traceback (most recent call last):
File "foo.py", line 3, in <module>
lib = ctypes.cdll.LoadLibrary('./foo.so')
File "/usr/local/Cellar/python3/3.6.4_2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ctypes/__init__.py", line 426, in LoadLibrary
return self._dlltype(name)
File "/usr/local/Cellar/python3/3.6.4_2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ctypes/__init__.py", line 348, in __init__
self._handle = _dlopen(self._name, mode)
OSError: dlopen(./foo.so, 6): Symbol not found: _caml_code_area_end
Referenced from: ./foo.so
Expected in: flat namespace
in ./foo.so

我在编译器的目录 ocamlopt -where 中四处寻找符号。

$ find `ocamlopt -where` | xargs -I% bash -c 'nm % | sed -e "s|^|%:|"' | & grep _caml_code_area_end
/usr/local/lib/ocaml/libasmrun_pic.a: 0000000000000008 C _caml_code_area_end
/usr/local/lib/ocaml/libasmrun_pic.a: U _caml_code_area_end
/usr/local/lib/ocaml/libasmrunp.a: 0000000000000008 C _caml_code_area_end
/usr/local/lib/ocaml/libasmrunp.a: U _caml_code_area_end
/usr/local/lib/ocaml/libasmrun_shared.so: 000000000001ded0 S _caml_code_area_end
/usr/local/lib/ocaml/libasmrun.a: 0000000000000008 C _caml_code_area_end
/usr/local/lib/ocaml/libasmrun.a: U _caml_code_area_end
/usr/local/lib/ocaml/libasmrund.a: 0000000000000008 C _caml_code_area_end
/usr/local/lib/ocaml/libasmrund.a: U _caml_code_area_end

并首先尝试加载 /usr/local/lib/ocaml/libasmrun_shared.so,给出

import ctypes

lib = ctypes.cdll.LoadLibrary('/usr/local/lib/ocaml/libasmrun_shared.so')
lib = ctypes.cdll.LoadLibrary('./foo.so')

print("Loaded")

产生错误的地方:

OSError: dlopen(/usr/local/lib/ocaml/libasmrun_shared.so, 6): Symbol not found: _caml_apply2
Referenced from: /usr/local/lib/ocaml/libasmrun_shared.so
Expected in: flat namespace
in /usr/local/lib/ocaml/libasmrun_shared.so

_caml_apply2 符号在 OCaml 的运行时中很深,我无法为它找到扩展名为 .so 的文件 ... 和 cdll 似乎没有公开加载 .as 的能力。

最佳答案

出于某种原因,-fPIC 标志还不够,您还需要一个 PIC 运行时。以前,这需要一个特殊的开关(例如 4.04.1+fPIC),但现在您可以选择要链接到哪个运行时。

以下对我有效(Debian buster,opam 4.06.1+rc2 switch):

% ocamlopt -output-obj -runtime-variant _pic -o foo.so foo.ml
% python foo.py
Loaded

I'm trying to build a shared object out of an OCaml library that I can run under Python using the cdll interface in ctypes.

请注意,您不能只从 Python(或其他接口(interface))调用 OCaml 符号,您需要编写一些 C 来设置运行时和管理 OCaml 对象。一个简单的方法是使用 Cstubs_inverted对于这部分。

关于python - OCaml 生成与 OCaml 运行时链接的共享对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48801340/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com