C FFI
Demonstrate the C-FFI of your language. Show how to wrap an hypothetic C library that contains these three functions in its header file:
void myfunc_a(); float myfunc_b(int, float); char *myfunc_c(int *);
The header file is named "mylib.h", and link against the lib with -lmylib and compile with -I/usr/include/mylib. Provide all the files included a Makefile.
OCaml
file "mylib.ml": <lang ocaml>external myfunc_a: unit -> unit = "caml_myfunc_a" external myfunc_b: int -> float -> float = "caml_myfunc_b" external myfunc_c: int array -> string = "caml_myfunc_c"</lang>
file "wrap_mylib.c": <lang C>#include <caml/mlvalues.h>
- include <caml/alloc.h>
- include <mylib.h>
CAMLprim value caml_myfunc_a(value unit) {
myfunc_a(); return Val_unit;
}
CAMLprim value caml_myfunc_b(value a; value b) {
float c = myfunc_b(Int_val(a), Double_val(b)); return caml_copy_double(c);
}
CAMLprim value caml_myfunc_c(value ml_array) {
int i, len; int *arr; char *s; len = Wosize_val(ml_array); arr = malloc(len * sizeof(int)); for (i=0; i < len; i++) { arr[i] = Int_val(Field(ml_array, i)); } char *s = myfunc_c(int *); free(arr); return caml_copy_string(s);
}</lang>
the Makefile: <lang Makefile>wrap_mylib.o: wrap_mylib.c
ocamlc -c -ccopt -I/usr/include/mylib $<
dllmylib_stubs.so: wrap_mylib.o
ocamlmklib -o mylib_stubs $< -lmylib
mylib.mli: mylib.ml
ocamlc -i $< > $@
mylib.cmi: mylib.mli
ocamlc -c $<
mylib.cmo: mylib.ml mylib.cmi
ocamlc -c $<
mylib.cma: mylib.cmo dllmylib_stubs.so
ocamlc -a -o $@ $< -dllib -lmylib_stubs -cclib -lmylib
mylib.cmx: mylib.ml mylib.cmi
ocamlopt -c $<
mylib.cmxa: mylib.cmx dllmylib_stubs.so
ocamlopt -a -o $@ $< -cclib -lmylib_stubs -cclib -lmylib
clean:
rm -f *.[oa] *.so *.cm[ixoa] *.cmxa</lang>
the file mylib.cma is used for the interpreted and bytecode modes, and mylib.cmxa is for the native mode.