繁体   English   中英

OCaml共享另一个共享库的lib

[英]OCaml shared lib for another shared lib

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

TL:DR; 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}

而我的问题是只有printf("Getting Called by Make\\n"); 当我在Makefile中添加适当的load do_speak.so时, caml_startup正在关闭, 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共享库的一部分,我显然没有caml_startup想要的原始argv指针。 正如我的代码示例所示,我已经尝试伪装它,并且还使用了caml_startup(NULL)char **argv = {NULL}; caml_startup(argv) char **argv = {NULL}; caml_startup(argv)同样缺乏成功。 我不知道如何正确初始化运行时。

我实际上不能很好地说出你在问什么。 但是,这是对您问题的这一部分的评论:

我试过把它伪装掉,还使用了caml_startup(NULL)和char ** argv = {NULL}; caml_startup(argv)同样缺乏成功。 我不知道如何正确初始化运行时。

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

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

从技术上讲, argv应该包含至少一个字符串(程序的名称)。 所以也许最好像这样打电话:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM