在 C 中调用需要 unix.cma 的 OCaml 函数

标签 c ocaml

我有一个 OCaml 库和一些用 C 语言围绕它定义的包装器。 我按照 http://caml.inria.fr/pub/docs/manual-ocaml/intfc.html 中的步骤操作(第 19.8 节)编译 main.c 程序 这样我就可以测试一切。

问题是,当通过

初始化 OCaml 引擎时
caml_startup(argv); 

它让我犯了很多错误。其中之一是:

Undefined symbols for architecture x86_64:
"_unix_truncate", referenced from:
  _caml_builtin_cprim in modcaml.o

我该如何解决这个问题?

使用外部库时是否需要某种特殊链接?

编辑:

编译我使用

cc -o prog -I `ocamlc -where` main.c mod.a -ltermcap

正如INRIA的说明。

主要代码是用OCaml写的。

最佳答案

一般来说,使用 ocamlbuild 将 ocaml 字节码生成为 .o 或 C 文件非常简单:

ocamlbuild program.byte.c

ocamlbuild program.byte.o

或使用不错的 RWO 书中的说明: https://realworldocaml.org/v1/en/html/the-compiler-backend-byte-code-and-native-code.html

但是对于下一步,我们想要将字节代码与我们的 C 代码合并,我们将遇到一些愚蠢的困难,以防我们的代码依赖于其他 ocaml 包。 由于您更喜欢使用 C 编译器/链接器,因此有一些简单的技巧可以知道您在代码中使用的 ocaml 库的位置:

ocamlc -where

并且您可以使用 nm 实用程序查找 undefined symbol 所在的库:

find `ocamlc -where` -iname *.a |xargs nm -o |grep "T your_symbol"

如果您记得使用过哪些库,则可以使用更具体的管道:

find `ocamlfind query used_module` -iname *.a |xargs nm -o |grep "T your_symbol"

现在您知道所需的库及其路径,因此您可以修改 CC 的命令行。

关于在 C 中调用需要 unix.cma 的 OCaml 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37990080/

相关文章:

c - 从 gcc 中的内联汇编引用全局变量

recursion - 扩展相互递归的仿函数

runtime - append 过程的运行时是否为O(n)?

c - 我不断收到错误消息 : "Conflicting types for ' sqrt' "

c - 从文件系统读取数据 vs 将数据直接编译到程序中

c - 从系统调用刷新浏览器

ocaml - 在 Ocaml 中,如果我不想使用变量,如何避免未使用的变量警告?

module - OCaml 中的嵌套签名示例?

c - 为什么这个 OCaml 程序比我的 C 程序快?

c - 修改函数返回的内存地址内容