Monday, March 29, 2010 by samfuqua





I've found a way around this and haven't been able to find this tutorial posted anywhere else, so here's mine:





We'll be using a simple library that contains methods that add fixed integers to given integers. This library will use two files; there will be the actual library module and another what I call an "interface module", which is not to be confused with a module interface file.





Here's our interface module, with its module interface:





adding.mli :

val add_two : (int -> int) ref;;

adding.ml:

let add_two = ref (fun int -> int);;

So basically, we're saying that this module contains a value called add_two , which is a reference to a function that takes an int and returns an int .

We'll compile this with:

$ ocamlopt adding.mli $ ocamlopt -a -o adding.cmxa adding.ml

This will give us a library file called adding.cmxa , which we'll compile statically with our library implementation:





addingimpl.ml :

let add_two_impl i = i + 2;; Adding.add_two := add_two_impl;;

We'll compile this with:

$ ocamlopt -shared -o adding.cmxs adding.cmxa addingimpl.ml

This will give us a dynamically loadable plugin that provides an implementation for our add_two method. However, this is rather useless if you don't use it. Let's use it in main.ml :

let main () = try Dynlink.init () ; Dynlink.loadfile "adding.cmxs" ; print_endline (string_of_int (!(Adding.add_two) 5 )); with Dynlink.Error e -> print_endline (Dynlink.error_message e) ; exit 1 ;; main () ;;

Compile it with:

$ ocamlopt -o main dynlink.cmxa adding.cmxa main.ml

and you should be able to use it like this:

$ ./main 7

And there you have it. If you want to update your library by using a faster algorithm, you can simply recompile it against your .cmxa file and everything will be happy.

I've been toying with OCaml for a little while and I think it's a great language. It has some great features and is useful for a lot of applications. The one thing that bothered me, though, was the inability to compile programs with dynamic linking to libraries. There's the Dynlink module, but all the modules explicitly used in the module you're compiling have to have some sort of implementation associated with them.