gpt4 book ai didi

c - 另一个共享库的 OCaml 共享库

转载 作者:太空狗 更新时间:2023-10-29 15:06:58 33 4
gpt4 key购买 nike

我正在探索一些冒险的想法。

长话短说:博士; gnumake 能够使用可加载模块,我正在尝试使用 C 屏障来使用 OCaml,但在 OCaml 运行时初始化时遇到了问题。

我有这个 OCaml 代码:

(* This is speak_ocaml.ml *)
let do_speak () =
print_endline "This called from OCaml!!";
flush stdout;
"Some return value from OCaml"

let () =
Callback.register "speak" do_speak

我也有这个 C 代码:(是的,需要使用额外的 CAML 宏,但这里不相关)

#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include <gnumake.h>
#include <caml/mlvalues.h>
#include <caml/callback.h>
#include <caml/memory.h>
#include <caml/alloc.h>

int plugin_is_GPL_compatible;

char *ocaml_speaker(const char *func_name, int argc, char **argv)
{
char *answer =
String_val(caml_callback(*caml_named_value("speak"), Val_unit));

printf("Speaking and got: %s\n", answer);
char *buf = gmk_alloc(strlen(answer) + 1);
strcpy(buf, answer);
/* receive_arg */
return buf;
}

int do_speak_gmk_setup()
{
printf("Getting Called by Make\n");
// This is pretty critical, will explain below
char **argv = {"/home/Edgar/foo", NULL};
caml_startup(argv);
printf("Called caml_startup\n");
gmk_add_function("speak", ocaml_speaker, 1, (unsigned int)1, 1);
return 1;
}

我正在用这个 Makefile 编译它

all:
ocamlopt -c speak_ocaml.ml
ocamlopt -output-obj -o caml_code.o speak_ocaml.cmx
clang -I`ocamlc -where` -c do_speak.c -o do_speak.o

clang -shared -undefined dynamic_lookup -fPIC -L`ocamlc -where` -ldl \
-lasmrun do_speak.o caml_code.o -o do_speak.so

show_off:
echo "Speaker?"
${speak 123}

clean:
@rm -rf *.{cmi,cmt,cmi,cmx,o,cmo,so}

我的问题是当我在 Makefile 中添加适当的 load do_speak.so 时,只有 printf("Getting Called by Make\n"); 会关闭, caml_startup 没有正常启动。现在我正在调用 caml_startup 因为如果我不这样做,我会得到一个错误

Makefile:9: dlopen(do_speak.so, 9): Symbol not found: _caml_atom_table
Referenced from: do_speak.so
Expected in: flat namespace
in do_speak.so
Makefile:9: *** do_speak.so: failed to load. Stop.

这是因为 OS X 上的 clang 进行链接的方式,有关更多详细信息,请参见此处:http://psellos.com/2014/10/2014.10.atom-table-undef.html

我有点想法...我需要用 OCaml 代码创建一个 C 共享库,然后它需要成为另一个 C 共享库的一部分,我显然没有原始的 argv 指针 caml_startup想要。正如我的代码示例所示,我尝试伪造它,还使用了 caml_startup(NULL)char **argv = {NULL}; caml_startup(argv) 也没有成功。我不知道如何正确初始化运行时。

最佳答案

其实我不太清楚你在问什么。但是,这是对您问题的这一部分的评论:

I've tried faking it out, and also used caml_startup(NULL) and char **argv = {NULL}; caml_startup(argv) with similar lack of success. I don't know how else to initialize the runtime correctly.

据我所知,caml_startupargv 参数的唯一原因是建立命令行参数(对于 Sys.argv)。如果您不需要命令行参数,可以这样调用:

char *arg = NULL;
caml_startup(&arg);

从技术上讲,argv 应该包含至少一个字符串(程序名称)。所以也许这样调用会更好:

char *argv[] = { "program", NULL };
caml_startup(argv);

关于c - 另一个共享库的 OCaml 共享库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35250031/

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