I'm trying to set up dynamic loading of OCaml modules using Dynlink. I wrote a very simple test program, but it's not working.
This test program consists of two modules, Plug and Ext. Plug is the "main" module. It knows the filename of Ext and loads it with Dynlink.loadfile
. Ext references Plug, and calls a function in Plug that informs Plug about one of its functions so that it can be called. After Plug loads Ext, it calls the function that Ext is supposed to have registered.
The Ext module loads successfully if I write it so that it doesn't execute any code. However, if I include the part that registers its extension function with Plug, then I get an error: The module 'Plug' is not yet initialized
.
I don't understand how Plug could not be initialized yet, since it is already executing. (Actually I don't know what it means for an OCaml module to be initialized.)
I've reduced the code down to pretty much the least necessary to reproduce the problem. I am using OCaml 4.01.0 on Linux.
Here's the main module:
(* 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 ()
This is the extension file:
(* ext.ml *)
open Plug
let myext str =
print_endline ("Ext: " ^ str)
let () = Plug.register myext
I used this shell script to compile the executable:
#!/bin/sh
ocamlc -c plug.ml && \
ocamlc -c ext.ml && \
ocamlc -o plug dynlink.cma plug.cmo ext.cmo \
|| exit 1
This is the output I get:
Loading ext.
error while linking ext.cmo.
The module `Plug' is not yet initialized
Calling registered func.
Dummy: calling
It looks like I was not on the ball with my search engine skills in this case.
Some more digging turned up an archived email chain that states that the referenced module ( Plug
in this case) must have been completely evaluated before the dynamically loaded module can call into it.
The solution is to separate the code that loads the extension module and the code that the extension module calls into two separate modules (so now there will be three modules in total).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.