You are currently browsing the archives for the c tag.

Ciml : C in OCaml

Olivier has been busy extending my previous work on inlining C in OCaml, and it is pretty cool. You can get it from the following darcs repository.

darcs get http://chadok.info/darcs/ciml/

Basically, it allows you to inline C in OCaml code, in a very fashionable way. Type conversion between OCaml and C is (almost always) automatically dealt with for base types (int, float, bool, string, etc.) and you can register and unregister custom converters. A few examples are shown in the test.ml.

letext hello (s:string) : unit =  <<
  printf("Hello %s !\n", s);
  Return();
>>
letext add (a:int) (b:int) : int =  <<
  int c;
  c = a + b;
  Return(c);
>>

(* Unregister the converters for int *)
unregister_fromval : int
unregister_toval : int

(* Register converters *)
register_fromval "Int_val" "int" : int
register_toval "Val_int" : int

The idea behind all this syntaxic sugar for inlining C code in OCaml is to provide a natural way of using C and OCaml together to whoever wants to bind C libraries to OCaml. Of course, this is still under developement, and any ideas to improve it are welcome.

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:

<:c<
#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.

Downloaded : 93 times
File : inlinec-0.42.tar.gz
Size: 1.4 ko

Inlining C code in OCaml

A great thing about OCaml is the possibility of creating bindings with C. The bad thing about it is that it's a pain to do. Olivier and I are currently thinking about a way to make that less painful. Here is a first draft : inlining C code in OCaml, in order to avoir multiple files.

Using camlp4, we extract the quotations containing C code and we dump that in a temporary .c file, and compile it. Here is an example:

<:c<
#include <caml/mlvalues.h>
#include <caml/memory.h>
#include <caml/alloc.h>
#include <caml/custom.h>
>>

external add: int -> int -> int = "add"
<:c<
value add(value a, value b) {
  int c;
  CAMLparam2(a,b);
  c = Int_val(a) + Int_val(b);
  CAMLreturn(Val_int(c));
}
>>

let _ =
  Printf.printf "La réponse est %d\n%!" (add 21 21);

The thing we would like to do is the following:

let add a b = <:cfun<
  int c = Int_val(a) + Int_val(b);
  CAMLreturn(Val_int(c));
>>

Which would be converted to:

external add: int -> int -> int = "add"

value add (value a, value b) {
  CAMLparams2(a,b);
  int c = Int_val(a) + Int_val(b);
  CAMLreturn(Val_int(c));
}

Downloaded : 88 times
File : inlinec.tar.gz
Size: 732 o