OCaml作为C库,hello world示例 我希望通过将OCAML编译成包含C接口的静态或共享库,调用C++的OCAM代码。似乎解释了如何为OCaml创建C接口。但是我如何做和编译它呢?我如何获取在我的C++代码中加载的.h文件?< /p>

OCaml作为C库,hello world示例 我希望通过将OCAML编译成包含C接口的静态或共享库,调用C++的OCAM代码。似乎解释了如何为OCaml创建C接口。但是我如何做和编译它呢?我如何获取在我的C++代码中加载的.h文件?< /p>,c,functional-programming,ocaml,C,Functional Programming,Ocaml,另外,有人能解释一下这一部分吗: OCaml运行时系统包括三个主要部分:字节码 解释器、内存管理器和一组C函数 实现原语操作。有些字节码指令是 用于调用这些C函数,由它们在a中的偏移量指定 函数表原语表 我认为OCaml可以编译成本地机器语言。为什么它被编译成字节码并在运行时进行解释?它总是这样,还是仅适用于使用C接口编译的OCaml库?该页的大部分介绍了如何从OCaml调用C。您希望执行相反的操作,如中所述,靠近页面底部 当您进行本机编译时,正如您所说的,不涉及字节码。本机编译器ocamlop

另外,有人能解释一下这一部分吗:

OCaml运行时系统包括三个主要部分:字节码 解释器、内存管理器和一组C函数 实现原语操作。有些字节码指令是 用于调用这些C函数,由它们在a中的偏移量指定 函数表原语表


我认为OCaml可以编译成本地机器语言。为什么它被编译成字节码并在运行时进行解释?它总是这样,还是仅适用于使用C接口编译的OCaml库?

该页的大部分介绍了如何从OCaml调用C。您希望执行相反的操作,如中所述,靠近页面底部

当您进行本机编译时,正如您所说的,不涉及字节码。本机编译器ocamlopt生成Unix文件中的普通object.o和包含OCaml元数据的额外文件

如果您看一下,您将看到一个示例,其中主程序是用C编写的,调用了OCaml中定义的两个函数。在C++中,事情应该类似地工作。然而,我自己只在C中做过这件事

更新

下面是使用高级示例中的代码和回调生成的示例。我在Ubuntu 18.04.4 x86_64上运行这段代码

OCaml代码如下所示:

$ cat mod.ml
let rec fib n = if n < 2 then 1 else fib (n - 1) + fib (n - 1)

let format_result n = Printf.sprintf "Result is: %d\n" n

let () = Callback.register "fib" fib
let () = Callback.register "format_result" format_result
将C代码重命名为modwrap.cc。代码在OCaml手册一节中给出

$ head -6 modwrap.cc
#include <stdio.h>
#include <string.h>
#include <caml/mlvalues.h>
#include <caml/callback.h>

int fib(int n)
现在运行程序

$ ./myprog
fib(10) = Result is: 89
没有头文件的自动生成。在本例中,main.cc的外部行本质上是头文件。如果你想要一个头文件,你必须自己写这样的东西

更新2

以下是用于创建包含OCaml函数及其包装器的实际静态库的命令。这假设您已经完成了上面的编译来创建bigmod.o和modwrap.o:

$ cp $(ocamlopt -where)/libasmrun.a libmyoc.a
$ ar r libmyoc.a bigmod.o modwrap.o
现在可以在主代码.cc:< /p>中表示的C++代码中使用这个库。
$ g++ -o myprog -I $(ocamlopt -where) main.cc -L . -lmyoc -ldl
$ ./myprog
fib(10) = Result is: 89
更新3


我更新了上面的命令来处理Unbuntu。

该页的大部分内容描述了如何从OCaml调用C。您希望执行相反的操作,如中所述,靠近页面底部

当您进行本机编译时,正如您所说的,不涉及字节码。本机编译器ocamlopt生成Unix文件中的普通object.o和包含OCaml元数据的额外文件

如果您看一下,您将看到一个示例,其中主程序是用C编写的,调用了OCaml中定义的两个函数。在C++中,事情应该类似地工作。然而,我自己只在C中做过这件事

更新

下面是使用高级示例中的代码和回调生成的示例。我在Ubuntu 18.04.4 x86_64上运行这段代码

OCaml代码如下所示:

$ cat mod.ml
let rec fib n = if n < 2 then 1 else fib (n - 1) + fib (n - 1)

let format_result n = Printf.sprintf "Result is: %d\n" n

let () = Callback.register "fib" fib
let () = Callback.register "format_result" format_result
将C代码重命名为modwrap.cc。代码在OCaml手册一节中给出

$ head -6 modwrap.cc
#include <stdio.h>
#include <string.h>
#include <caml/mlvalues.h>
#include <caml/callback.h>

int fib(int n)
现在运行程序

$ ./myprog
fib(10) = Result is: 89
没有头文件的自动生成。在本例中,main.cc的外部行本质上是头文件。如果你想要一个头文件,你必须自己写这样的东西

更新2

以下是用于创建包含OCaml函数及其包装器的实际静态库的命令。这假设您已经完成了上面的编译来创建bigmod.o和modwrap.o:

$ cp $(ocamlopt -where)/libasmrun.a libmyoc.a
$ ar r libmyoc.a bigmod.o modwrap.o
现在可以在主代码.cc:< /p>中表示的C++代码中使用这个库。
$ g++ -o myprog -I $(ocamlopt -where) main.cc -L . -lmyoc -ldl
$ ./myprog
fib(10) = Result is: 89
更新3


我更新了上面的命令,以便在取消绑定上工作。

嘿,我刚刚尝试过,看一看:ocamlopt-output obj-o mod.o mod.ml mod.o:文件未识别:文件截断文件caml\u启动,第1行:错误:链接期间出错我不知道如何消除这个错误,你知道发生了什么吗?显然ocamlopt-output obj-o mod.o mod.ml不起作用,但是如果我执行ocamlopt-output obj-o OTHER_NAME.o mod.ml,我会在同一个文件夹中生成OTHER_NAME.o和mod.o。为什么?我明白问题所在。基本问题是最终输出mod.o不应该与编译mod.ml生成的中间文件mod.o同名。我会更新我的答案。不管好坏我的答案适用于mac OS,我不知道为什么。还有一个问题:g++-o hello_world-I$ocamlopt-where\main.cc say_something.cc s.o$ocamlopt-where/libasmrun.a给出了很多未定义的引用:/root/.opam/4.10.0/.opam开关/build/ocaml基本编译器。4.10.0/runtime/unix.c:284:dlclose的未定义引用/root/.opam/4.10.0/lib/ocaml/libasmrun.aunix_n.o:在函数caml_dlsym':/root/.opam/4.10.0/.opam开关/build/ocaml基编译器.4.10.0/runtime/unix.c:289:对dlsym'/root/.opam/4.10.0/.opam开关/build/ocaml基编译器的未定义引用.4.10.0/runtime/unix.c:289:未定义引用toHey,I
刚试过,看一看:ocamlopt-output obj-o mod.o mod.ml mod.o:文件未识别:文件截断文件caml_启动,第1行:错误:链接过程中出错我不知道如何解决这个问题,你知道发生了什么吗?显然ocamlopt-output obj-o mod.o mod.ml不起作用,但是如果我执行ocamlopt-output obj-o OTHER_NAME.o mod.ml,我会在同一个文件夹中生成OTHER_NAME.o和mod.o。为什么?我明白问题所在。基本问题是最终输出mod.o不应该与编译mod.ml生成的中间文件mod.o同名。我会更新我的答案。不管好坏我的答案适用于mac OS,我不知道为什么。还有一个问题:g++-o hello_world-I$ocamlopt-where\main.cc say_something.cc s.o$ocamlopt-where/libasmrun.a给出了很多未定义的引用:/root/.opam/4.10.0/.opam开关/build/ocaml基本编译器。4.10.0/runtime/unix.c:284:dlclose的未定义引用/root/.opam/4.10.0/lib/ocaml/libasmrun.aunix_n.o:在函数caml_dlsym':/root/.opam/4.10.0/.opam开关/build/ocaml base compiler.4.10.0/runtime/unix.c:289:对dlsym'/root/.opam/4.10.0/.opam开关/build/ocaml base compiler.4.10.0/runtime/unix.c:289:未定义的引用