Ocaml/C 使用 bigarray 的互操作:'undefined symbol: caml_ba_alloc'
Ocaml/C interop using bigarray: 'undefined symbol: caml_ba_alloc'
我正在尝试编译使用 bigarray 的 'Hello World' 级 Ocaml/C 互操作程序。我收到有关 undefined symbol: caml_ba_alloc
的错误(详情如下)。好像应该由bigarray.h
.
提供
这是我的文件:
wrap_mylib.c:
#include <caml/bigarray.h>
#include <caml/mlvalues.h>
#include <caml/memory.h>
CAMLprim value caml_fn(value x) {
float* result = malloc(sizeof(float));
long dims[] = {1, 1};
return caml_ba_alloc(CAML_BA_NATIVE_INT, 2, result, dims);
}
mylib.ml
:
external ext_caml_fn : int -> (float, Bigarray.float32_elt, Bigarray.c_layout) Bigarray.Array2.t
= "caml_fn" ;;
Makefile
:
wrap_mylib.o: wrap_mylib.c
gcc -c wrap_mylib.c
another_wrapper.so: wrap_mylib.o
cc -shared -o another_wrapper.so wrap_mylib.o
mylib.mli: mylib.ml
ocamlc -i $< > $@
mylib.cmi: mylib.mli
ocamlc -c $<
mylib.cmo: mylib.ml mylib.cmi
ocamlc -c $<
mylib_test: mylib.cmo another_wrapper.so
ocamlc -linkall -o mylib_test mylib.cmo another_wrapper.so
clean:
rm *.cma *.cmo *.cmi *.cmx *.cmxa *.mli *.o *.a *.so
这是我尝试编译时的输出 mylib_test
:
$ make mylib_test
ocamlc -i mylib.ml > mylib.mli
ocamlc -c mylib.mli
ocamlc -c mylib.ml
gcc -c wrap_mylib.c
cc -shared -o another_wrapper.so wrap_mylib.o
ocamlc -linkall -o mylib_test mylib.cmo another_wrapper.so
File "_none_", line 1:
Error: Error on dynamically loaded library: ./another_wrapper.so: ./another_wrapper.so: undefined symbol: caml_ba_alloc
Makefile:17: recipe for target 'mylib_test' failed
make: *** [mylib_test] Error 2
环境
OS: Ubuntu 18.04.2 LTS(仿生海狸)
$ ocaml --version
The OCaml toplevel, version 4.05.0
谢谢!
像bigarray.h
这样的文件定义了在编译时有用的东西。但是你的问题是link次的问题。您需要找到包含您要查找的函数的库,并将其包含在 link 步骤中。
如果我使用 ocamlopt(本机代码实现)并使用普通目标文件(OCaml .cmx 和 C .o)而不是共享库,我可以像这样 link 得到东西:
$ ocamlopt -c mylib.ml
$ gcc -I $(ocamlc -where) -c wrap_mylib.c
$ ocamlopt -o mylib_test wrap_mylib.o mylib.cmx
这会生成一个可执行文件 mylib_test 我可以 运行:
$ ./mylib_test
$
当然,当我 运行 可执行文件时什么也没有发生,因为你的文件 mylib.ml 中没有顶级代码。所以这只是测试事情是否会 link 正常。
希望对您有所帮助。
回答我自己的问题。这是我如何让它工作的。通过链接 bigarray.cma
:
编译 mylib_test
ocamlc -linkall -o mylib_test mylib.cmo another_wrapper.so bigarray.cma
然后 运行 与:
LD_LIBRARY_PATH=. ./mylib_test
LD_LIBRARY_PATH=.
是它在同一目录中找到共享库 another_wrapper.so
所必需的。
根据 https://caml.inria.fr/pub/docs/manual-ocaml/libbigarray.html bigarray
现在是标准库的一部分,因此只有在使用旧版兼容性库时才需要链接 bigarray.cma
。可能是我的标准库版本太旧了。
我正在尝试编译使用 bigarray 的 'Hello World' 级 Ocaml/C 互操作程序。我收到有关 undefined symbol: caml_ba_alloc
的错误(详情如下)。好像应该由bigarray.h
.
这是我的文件:
wrap_mylib.c:
#include <caml/bigarray.h>
#include <caml/mlvalues.h>
#include <caml/memory.h>
CAMLprim value caml_fn(value x) {
float* result = malloc(sizeof(float));
long dims[] = {1, 1};
return caml_ba_alloc(CAML_BA_NATIVE_INT, 2, result, dims);
}
mylib.ml
:
external ext_caml_fn : int -> (float, Bigarray.float32_elt, Bigarray.c_layout) Bigarray.Array2.t
= "caml_fn" ;;
Makefile
:
wrap_mylib.o: wrap_mylib.c
gcc -c wrap_mylib.c
another_wrapper.so: wrap_mylib.o
cc -shared -o another_wrapper.so wrap_mylib.o
mylib.mli: mylib.ml
ocamlc -i $< > $@
mylib.cmi: mylib.mli
ocamlc -c $<
mylib.cmo: mylib.ml mylib.cmi
ocamlc -c $<
mylib_test: mylib.cmo another_wrapper.so
ocamlc -linkall -o mylib_test mylib.cmo another_wrapper.so
clean:
rm *.cma *.cmo *.cmi *.cmx *.cmxa *.mli *.o *.a *.so
这是我尝试编译时的输出 mylib_test
:
$ make mylib_test
ocamlc -i mylib.ml > mylib.mli
ocamlc -c mylib.mli
ocamlc -c mylib.ml
gcc -c wrap_mylib.c
cc -shared -o another_wrapper.so wrap_mylib.o
ocamlc -linkall -o mylib_test mylib.cmo another_wrapper.so
File "_none_", line 1:
Error: Error on dynamically loaded library: ./another_wrapper.so: ./another_wrapper.so: undefined symbol: caml_ba_alloc
Makefile:17: recipe for target 'mylib_test' failed
make: *** [mylib_test] Error 2
环境
OS: Ubuntu 18.04.2 LTS(仿生海狸)
$ ocaml --version
The OCaml toplevel, version 4.05.0
谢谢!
像bigarray.h
这样的文件定义了在编译时有用的东西。但是你的问题是link次的问题。您需要找到包含您要查找的函数的库,并将其包含在 link 步骤中。
如果我使用 ocamlopt(本机代码实现)并使用普通目标文件(OCaml .cmx 和 C .o)而不是共享库,我可以像这样 link 得到东西:
$ ocamlopt -c mylib.ml
$ gcc -I $(ocamlc -where) -c wrap_mylib.c
$ ocamlopt -o mylib_test wrap_mylib.o mylib.cmx
这会生成一个可执行文件 mylib_test 我可以 运行:
$ ./mylib_test
$
当然,当我 运行 可执行文件时什么也没有发生,因为你的文件 mylib.ml 中没有顶级代码。所以这只是测试事情是否会 link 正常。
希望对您有所帮助。
回答我自己的问题。这是我如何让它工作的。通过链接 bigarray.cma
:
mylib_test
ocamlc -linkall -o mylib_test mylib.cmo another_wrapper.so bigarray.cma
然后 运行 与:
LD_LIBRARY_PATH=. ./mylib_test
LD_LIBRARY_PATH=.
是它在同一目录中找到共享库 another_wrapper.so
所必需的。
根据 https://caml.inria.fr/pub/docs/manual-ocaml/libbigarray.html bigarray
现在是标准库的一部分,因此只有在使用旧版兼容性库时才需要链接 bigarray.cma
。可能是我的标准库版本太旧了。