我試圖設置使用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