Inlining C code in OCaml, part II
I finally managed to do what I was talking about this morning. There are a few awful things in the code, but it works.
Here is what one can write:
#include <stdio.h>
>>
ext add (a:int) (b:int) : int = <:cfun<
int c;
c = Int_val(a) + Int_val(b);
CAMLreturn(Val_int(c));
>>
ext hello (s:string) : unit = <:cfun<
printf("Hello %s !\n", String_val(s));
CAMLreturn(Val_unit);
>>
ext ping_pong (n:int) : int = <:cfun<
int c = Int_val(caml_callback( *caml_named_value("fact"), n));
printf("C : ping. fact 4 = %d\n", c);
CAMLreturn(Val_int(c));
>>
let fact n =
let rec fact acc = function
0 -> acc
| n -> fact (n*acc) (n-1)
in
fact 1 n
let _ =
Callback.register "fact" fact;
Printf.printf "%d\n%!" (add 1 5);
Printf.printf "Ocaml : pong. fact 4 = %d\n%!" (ping_pong 4);
hello "World";
The ext keyword is the equivalent of let to define external functions. All types must be specified (for the arguments and for the return value. Camlp4 the generates the C function, the external declaration etc.
2 Responses to "Inlining C code in OCaml, part II"
Intéressant ! J'avais trouvé la complexité de camlp4 assez décourageante, mais je ne pensais pas que c'était aussi puissant : inliner directement le c offre pas mal de possibilités (oui, j'ai pas grand chose à dire, mais c'est plutôt un message d'encouragement).
En fait ce n'est pas exactement ça : tout ce que fait camlp4 ici, c'est séparer le code caml du code C, générer les bonnes directives "external" de caml et mettre tout le code C dans un fichier temporaire qui sera compilé. Au final ca revient à inliner du C, mais la compilation est faite "plus tard".
Leave a Reply