我在定义接受 anuint64_t和 a的 C void 函数的签名时遇到问题char*。我试过了int64 -> string -> _。
我也不知道如何一起编译我的 C++ 文件(带有 C 接口)
事件.ml
open Lwt.Infix
external call: int64 -> string -> _ = "function_pointer_caller"
let begin_event pointer =
Lwt_unix.sleep 5.0 >>= fun () ->
call pointer "message"
let () = Callback.register "begin_event" begin_event
接口.c:
#include <stdio.h>
#include <string.h>
#include <caml/mlvalues.h>
#include <caml/callback.h>
#include <caml/alloc.h>
#include <caml/bigarray.h>
extern void register_function_callback();
void print_from_event(char* message) {
printf("OCaml event: %s\n", message);
}
void function_pointer_caller(uint64_t pointer, char* message)
{
void (*f)(char *);
f = pointer;
}
void register_function_callback() {
static const value *begin_event_closure = NULL;
if (begin_event_closure == NULL)
{
begin_event_closure = caml_named_value("begin_event");
if (begin_event_closure == NULL)
{
printf("couldn't find OCaml function\n");
exit(1);
}
}
uint64_t pointer = (uint64_t) &function_pointer_caller;
caml_callback(*begin_event_closure, (int64_t) &pointer);
}
主文件
#include <stdio.h>
#include <caml/callback.h>
extern "C" void register_function_callback();
int main(int argc, char **argv)
{
caml_startup(argv);
register_function_callback();
while (true)
{
}
return 0;
}
我认为没有办法将 .cc 与 .ml 一起编译,因为 .cc 不一定有 C 接口。也许可以将 .ml 编译为 .so 对象并使用 C 接口将其链接到 .cc ?
无论如何,我确实更改interface.cc并interface.c添加interface.c到ocamlopt命令中:
ocamlfind ocamlopt -o s -linkpkg -package lwt.unix -thread event_emitter.ml interface.c
g++ -o event_emitter_program -I $(ocamlopt -where) \
s.o interface.o main.cc event_emitter.o $(ocamlopt -where)/libasmrun.a -ldl
第一个命令编译正常,但 g++ 给出
event_emitter.o: In function `camlEvent_emitter__begin_event_90':
:(.text+0x3f): undefined reference to `camlLwt_unix__sleep_695'
:(.text+0x4c): undefined reference to `camlLwt__bind_1276'
collect2: error: ld returned 1 exit status
请注意,我插入了interface.o上一个命令 ( ocamlopt) 并在 g++ 中链接,因为ocamlopt实际上将 C 文件传递给 C 编译器。
我不知道为什么它会抱怨Lwt_unix,因为我已经在ocamlopt.