我遇到一个问题,我有一个全局哈希表,然后我使用 Dynlink 加载一个 .cma 文件,该文件在哈希表中注册了一个函数。
但是,我似乎看到的行为是,当动态链接模块时,所有全局绑定(bind)都会重新初始化,因此我的哈希表为空。
例如:
Table.extensions : (string, string -> string) Hashtbl.t
Extensions.load : unit -> unit (* loads the specified .cma files *)
Extensions.register : string -> (string -> string) -> unit
(* adds entry to Table.extensions, prints name of extension registered *)
Main:
let () =
Extensions.load ();
Hashtbl.iter (fun x _ -> print_endline x) Table.extensions;
Printf.printf "%d extensions loaded\n" (Hashtbl.length Table.extensions)
我的程序加载一个 .cma 文件,因此它应该打印:
Registered extension 'test'
test
1 extensions loaded
相反,我得到:
Registered extension 'test'
0 extensions loaded
我已经为此奋斗了几个小时了;无论我如何重构代码,我都无法接近可行的解决方案。
编辑:Extensions.load:
Dynlink.allow_unsafe_modules true;;
let load () =
try
let exts = Sys.readdir "exts" in
Array.iter begin fun name ->
try
Dynlink.loadfile (Filename.concat "exts" name);
Printf.printf "Loaded %s\n" name;
with
| Dynlink.Error error -> print_endline (Dynlink.error_message error)
| exn -> print_endline (Printexc.to_string exn)
end exts
with _ -> ()
最佳答案
@ygrek,你是对的,有两个实例。
解决方案是仅构建/加载 .cmo
,而不是 .cma
。
关于ocaml - 使用 dynlink 加载模块重新初始化顶层值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4712296/