Ciml
-Information
- --
-
- Authors
-
-
-
-
- Adrien Friggeri -
- Olivier Schwander -
- - Version : 0.42 -
- Licence : ? -
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 :
- --
-
- Several includes, those are needed in order to link OCaml and C -
CAMLParam1
andCAMLreturn
, those are used to deal with the garbarge collector
-#define Return(foo)
, this allows you to simply writeReturn()
at the end -of your function, instead of some complex stuff.
-- ... actually, Ciml does much more than that... -
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
-
-
-
-