我试图设置使用Dynlink的OCaml模块的动态加载。我写了一个非常简单的测试程序,但它不起作用。试图用Dynlink动态加载模块
该测试程序由两个模块组成,即Plug和Ext。插头是“主”模块。它知道Ext的文件名并用Dynlink.loadfile
加载它。 Ext引用Plug,并在Plug中调用一个函数,通知插入其中的一个函数,以便调用它。在Plug载入Ext后,它会调用Ext应该注册的函数。
如果我编写它,Ext模块将不会成功加载,因此它不会执行任何代码。但是,如果我将包含其扩展功能的部分包含在Plug中,则会出现错误:The module 'Plug' is not yet initialized
。
我不明白如何插入无法初始化,因为它已经执行。 (实际上我不知道OCaml模块初始化意味着什么。)
我已经将代码降低到几乎不需要重现该问题的程度。我在Linux上使用OCaml 4.01.0。
这里的主要模块:
(* plug.ml *)
type xfn = string -> unit
let dummy_func str =
print_endline ("Dummy: "^str)
let ext_func : xfn ref = ref dummy_func
let register func =
ext_func := func
let call() =
(!ext_func) "calling"
(* load extension *)
let() =
try
print_endline "Loading ext.";
Dynlink.loadfile "ext.cmo";
print_endline "Loaded ext.";
()
with
| Dynlink.Error e ->
print_endline (Dynlink.error_message e);
print_endline "Calling registered func.";
call()
这是扩展文件:
(* ext.ml *)
open Plug
let myext str =
print_endline ("Ext: "^str)
let() = Plug.register myext
我用这个shell脚本编译可执行文件:
#!/bin/sh
ocamlc -c plug.ml && \
ocamlc -c ext.ml && \
ocamlc -o plug dynlink.cma plug.cmo ext.cmo \
|| exit 1
这是输出我得到:
Loading ext.
error while linking ext.cmo.
The module `Plug' is not yet initialized
Calling registered func.
Dummy: calling