开发者

Loading module with dynlink re-initialises top-level values

I have a problem where I have a global hashtable, and then I load a .cma file with Dynlink, which registers a function in the hashtable.

However, the behaviour I seem to be see is that when the module is dynamically linked, all the global bindings get re-initialised, such that my hashtable is empty.

E.g.:

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)

My program loads one .cma file, so it should print:

Registered extension 'test'
test
1 extensions loaded

Instead I get:

Registered extension 'test'
0 extensions loaded

I've been fighting this for several hours now; no matter how I refactor my code, I get no closer to a working solution.

EDIT: 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 "ex开发者_如何转开发ts" 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, you were right, there were two instances.

The solution was to build/load just the .cmo, not a .cma.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜