Hello. Not sure if this should have gone to beginners or the regular list. Also not sure if its been answered before. If so, please redirect me! I did a bunch of searching both on google and in the lists and couldn't find the answers I needed. So here goes. I have written a blob of code in Ocaml that I like very much. I'd love to keep it in ocaml and not have to worry about things like memory leaks and so on. However, much of what I do is in C and can't be in Ocaml. So I am investigating packing my nice Ocaml code into a library and writing C bindings so that I can talk to it. Virtually all of the tutorials out there and documentation cover how to create Ocaml bindings to a C library. I don't want to do that. The few examples I have found that are relevant are toy ones. How to write C bindings to an Ocaml "fib" function, e.g. In particular, I have found none that cover how to obtain pointers to OCaml function return values that are not strings or ints, how to store them in C-land, and how to pass them back to Ocaml as parameters. Let's take as a concrete example the following: creating C bindings for a simple hash table mapping string keys to integer values. If I can generate bindings for this that work I should be able to do so for the library I really care about. Here's what I put together for the hash table slightly-less-than-toy example. It doesn't even compile. [Oddly, with very similar incantations my own code does compiles but then segfaults inside one of the Ocaml fns.] Any help much appreciated! -Tim 1. The implementation. % cat ht.ml type ht = (string,int) Hashtbl.t let create () : ht = Hashtbl.create 100 let add (table:ht) key valu = Hashtbl.add table key valu let mem (table:ht) key = Hashtbl.mem table key let remove (table:ht) key = if (Hashtbl.mem table key) then Hashtbl.remove table key let _ = Callback.register "create" create let _ = Callback.register "add" add let _ = Callback.register "mem" mem let _ = Callback.register "remove" remove 2. The wrappers % cat ht_wrap.c #include #include #include void *ht_create (void) { static value *create_closure = NULL; if (create_closure == NULL) create_closure = caml_named_value("create"); return ((void *) (caml_callback(*create_closure, Val_unit))); } void ht_add (void *ht, char *key, int val) { static value *add_closure = NULL; if (add_closure == NULL) add_closure = caml_named_value("add"); caml_callback3(*add_closure, (value) ht, caml_copy_string(key), Val_int(val)); } void ht_mem (void *ht, char *key) { static value *mem_closure = NULL; if (mem_closure == NULL) mem_closure = caml_named_value("mem"); caml_callback2(*mem_closure, (value) ht, caml_copy_string(key)); } void ht_remove (void *ht, char *key) { static value *remove_closure = NULL; if (remove_closure == NULL) remove_closure = caml_named_value("remove"); caml_callback2(*remove_closure, (value) ht, caml_copy_string(key)); } 3. Header file for those wrappers % cat ht.h void *ht_create (void); void ht_add (void *ht, char *key, int val); void ht_mem (void *ht, char *key); void ht_remove (void *ht, char *key); 4. The test program, with main() function. % cat ht_test.c #include #include "ht.h" int main (int argc, char **argv) { void *ht; caml_startup(argv); ht = ht_create(); ht_add(ht, "foo", 1); ht_add(ht, "foo", 1); ht_add(ht, "bar", 1); ht_remove(ht, "foo"); } 5. And this is how I am attempting to compile it. Note that error I'm getting here is in link. If I add "-lm" it gets less noisy but still is mad at me. Why am I having to add math library? Again, help!! % ocamlopt -output-obj -o ht.o ht.ml % ocamlopt -c ht_wrap.c % cp /usr/lib/ocaml/3.10.0/libasmrun.a ./ht.a % ar r ht.a ht_wrap.o ht.o % gcc -o htt ht_test.c ht.a -lcurses ht.a(floats.o): In function `caml_ceil_float': (.text+0x193): undefined reference to `ceil' ht.a(floats.o): In function `caml_atan2_float': (.text+0x1ae): undefined reference to `atan2' ht.a(floats.o): In function `caml_atan_float': (.text+0x1c5): undefined reference to `atan' ht.a(floats.o): In function `caml_acos_float': (.text+0x1dc): undefined reference to `acos' ht.a(floats.o): In function `caml_asin_float': (.text+0x1f3): undefined reference to `asin' ht.a(floats.o): In function `caml_tanh_float': (.text+0x20a): undefined reference to `tanh' ht.a(floats.o): In function `caml_tan_float': (.text+0x221): undefined reference to `tan' ht.a(floats.o): In function `caml_cosh_float': (.text+0x238): undefined reference to `cosh' ht.a(floats.o): In function `caml_cos_float': (.text+0x24f): undefined reference to `cos' ht.a(floats.o): In function `caml_sinh_float': (.text+0x266): undefined reference to `sinh' ht.a(floats.o): In function `caml_sin_float': (.text+0x27d): undefined reference to `sin' ht.a(floats.o): In function `caml_power_float': (.text+0x298): undefined reference to `pow' ht.a(floats.o): In function `caml_sqrt_float': (.text+0x2bf): undefined reference to `sqrt' ht.a(floats.o): In function `caml_log10_float': (.text+0x400): undefined reference to `log10' ht.a(floats.o): In function `caml_log_float': (.text+0x417): undefined reference to `log' ht.a(floats.o): In function `caml_fmod_float': (.text+0x551): undefined reference to `fmod' ht.a(floats.o): In function `caml_floor_float': (.text+0x568): undefined reference to `floor' ht.a(floats.o): In function `caml_exp_float': (.text+0x57f): undefined reference to `exp' ht.a(ht.o): In function `caml_program': (.text+0x46): undefined reference to `camlHt__entry' ht.a(ht.o): In function `caml_globals': (.data+0x2e0): undefined reference to `camlHt' ht.a(ht.o): In function `caml_data_segments': (.data+0x410): undefined reference to `camlHt__data_begin' ht.a(ht.o): In function `caml_data_segments': (.data+0x418): undefined reference to `camlHt__data_end' ht.a(ht.o): In function `caml_code_segments': (.data+0x488): undefined reference to `camlHt__code_begin' ht.a(ht.o): In function `caml_code_segments': (.data+0x490): undefined reference to `camlHt__code_end' ht.a(ht.o): In function `caml_frametable': (.data+0x4d8): undefined reference to `camlHt__frametable' collect2: ld returned 1 exit status -- When I see an adult on a bicycle, I do not despair for the future of the human race. - H. G.Wells