ocaml - 使用 dynlink 加载模块重新初始化顶层值

标签 ocaml

我遇到一个问题,我有一个全局哈希表,然后我使用 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/

相关文章:

ocaml - 为什么有些标准的 ocaml 库是 opam 包而有些不是?

f# - The Little ML'er - F# 的良好培训?

ocaml - 如何使 Ocaml 多态变体私有(private)

algorithm - Ocaml函数调用,递归调用自身

recursion - OCaml 递归调用不能有不同类型的参数?

f# - 模式匹配,F# 与 Erlang

list - 如何访问ocaml列表中的最后一个元素

ocaml - 测试是否在utop中运行

external - % 在 OCaml 外部声明中是什么意思?

ocaml - 为什么指数运算符在 OCaml 中使用 float 变量?