[remove html readme Olivier Schwander **20091126150757 Ignore-this: 94545f46f831a65f5dc422b5373cdf41 ] { hunk ./lib/ciml.htm 1 - - - - - - - Ciml - - - -
-
-

Ciml

-
-

Information

- - - -

Introduction

- -

Ciml is a Camlp4 extension -which allows the inlining of C code and provides helpers for type conversion -inside OCaml code. For example, one could use the following :

- -
letext hello (s:string) : unit =  << 
-  printf("Hello %s !\n", s);
-  Return();
->>
-
- -

How does it work ?

- -

It is important to understand how Ciml works in order to use it correctly. Ciml -does not compile C code, nor does it use Camlp4 to do so. What Ciml does is just -strip out the C code from the OCaml code, and write it to a temporary C file. -Using an intelligent Makefile you then compile that file and then link it to the -OCaml compiled module.

- -

Inlining C code

- -

The letext statement is very similar to OCaml's let statement, and they -share the same syntax. However, please note that letext statement's are only -allowed at a top level (not nested).

- -

Moreover, as the functions are declared as external, their type cannot be -infered. This is why one needs to manually declare all types (which should -nevertheless be done by using the external statement).

- -

C code is surrounded by << and >> which represents quotations for Camlp4. -If some C code is found at an expression level (inside a letext) it will -automatically be wrapped into a C function declaration. C code found at the top -level (statement level) will just be copied to the temporary C file.

- -

Here is an example :

- -
<<
-// this is some C code at the statement level
-// it is directly copied
-#include <stdio.h>
->>
-letext hello (s:string) : unit =  << 
-  printf("Hello %s !\n", s);
-  Return();
->>
-
- -

When preprocessed, the following file is created :

- -
#include <caml/mlvalues.h>
-#include <caml/alloc.h>
-#include <caml/memory.h>
-#include <caml/fail.h>
-#include <caml/callback.h>
-#include <caml/custom.h>
-#include <caml/intext.h>
-
-
-// this is some C code at the statement level
-// it is directly copied
-#include <stdio.h>
-
-value hello (value s__0) {
-  CAMLparam1(s__0);
-char* s = String_val(s__0);
-
-#define Return(foo) CAMLreturn(Val_unit)
-
-  printf("Hello %s !\n", s);
-  Return();
-
-#undef Return
-}
-
- -

You might notice that several other instructions were added to the source code :

- - - -

Type Conversion

- -

Here again, a little history: when a C function is called from OCaml as -external, OCaml passes its arguments with the value C type. One then uses -one of the Int_val, String_val, etc. macro to convert the value to -whatever type is needed.

- -

As Ciml is aware of the type of the arguments, automatic type converters are -implemented. For example, when one writes :

- -
letext hello (s:string) : unit =  << 
-  printf("Hello %s !\n", s);
-  Return();
->>
-
- -

The s argument is passed as a value to the C function, but there is an -automatic conversion using String_val (because we know that s is a string). -Conversely, returned values are automatically converted:

- -
// use:
-Return(42);
-// don't use:
-Return(Val_int(42));
-
- -

Currently, type converters are implemented for int, bool, float, string, -unit.

- -

Custom converters

- -

You can add and remove custom converters using the following syntax:

- -
(* add *)
-register_fromval "Int_val" "int" : int
-register_toval "Val_int" : int
-
-(* remove *)
-unregister_fromval : int
-unregister_toval : int
-
- - -
- - + rmfile ./lib/ciml.htm }