I have a system which uses Dynlink to dynamically load some code (.cmxs). The problem that I am having is that you cannot use the Object system in OCaml with Dynlink when naively compiling (I haven’t tried bytecode). I feel that I am missing some compiler option when compiling the code or I am misunderstanding how to use Dynlink. The error is below:
Is this a known issue when using Dynlink? Thank you very much for any help/ideas/suggestions that you may have.
A minimal example which shows the behavior is below:
obj_test.ml
class istack = object
val mutable v = [0; 2]
method pop =
match v with
| hd :: tl ->
v <- tl;
Some hd
| [] -> None
method push hd =
v <- hd :: v
end
which is complied thus: ocamlfind opt -shared -o obj_test.cmxs obj_test.ml
main.ml
let load_test_plugin fname =
let fname = Dynlink.adapt_filename fname in
try
Dynlink.loadfile fname
with
| (Dynlink.Error err) as e ->
print_endline ("ERROR loading plugin: " ^ (Dynlink.error_message err));
raise e
let _ =
load_test_plugin Sys.argv.(1)
which is compiled thus: ocamlfind opt -package dynlink -linkpkg main.ml
When you try to run the code: ./a.out obj_test.cmxs, you will get the error indicated above.
The problem is that the main program is not linked with the internal
values needed to handle object-based constructs (namely the CamlinternalOO module whose name appears as the prefix of the
undefined symbol).
A simple, yet unsatisfactory, workaround is to add this line to your
main file: let _ = object end, as it will force the link with the missing
module.
However, I think the problem deserves a bug report.
I recommend to put the “-linkall” link-time option when building an executable that is going to dynamically load stuff through the Dynlink interface, This way, all the definitions visible to the executable will be made available to the dynamically-loaded code.
Without “-linkall”, the OCaml static linker will delete the definitions that are not used – unless you add dummy uses for those definitions, as suggested in the previous replies, but it gets tiring after a while.
Indeed, the problem I am having with “-linkall” is that the linker is denying that modules exist even though they are installed and ocamlfind can find the packages. I will be able to look at this again but not right this moment. Thank you for your help!