ocaml-ctypes
ocaml-ctypes copied to clipboard
Add support for C functions which directly handle OCaml `value`s
This PR adds support for handling native OCaml values as arguments to and return values from C functions.
This makes it easy to use the OCaml allocator via caml_alloc_custom, while still allowing Ctypes to handle the other details of bindings, and without having to entirely rewrite existing binding systems. For example, in the Mina project we use bindings that currently allocate using rust's Box; it would be extremely useful to allocate on the OCaml heap without needing large changes to the bindings or the OCaml side.
The implementation roughly
- adds a new
typconstructorValue, where the parameter may be any OCaml type - fills out the generation code to pass the value directly and expose the
_OCaml type on the bindings - adds a
Value ()functor to the main interface- this creates a fresh type associated with a
typfor the value - the type is deliberately abstract, so that there is still some discipline enforced around distinct types being kept separate
- this creates a fresh type associated with a
- adds a few small tests, namely a
intnatclone and an[int]- these aren't particularly extensive (custom types only), but they work as expected.
Example usage:
module My_foreign_type = Value ()
let create = foreign "my_foreign_type_create" (int @-> bool @-> My_foreign_type.typ)
let get_int = foreign "my_foreign_type_get_int" (My_foreign_type.typ @-> returning int)
let get_bool = foreign "my_foreign_type_get_bool" (My_foreign_type.typ @-> returning bool)
let set_bool = foreign "my_foreign_type_set_bool" (My_foreign_type.typ @-> bool @-> returning void)
Corresponding C header:
value my_foreign_type_create(int i, bool b);
int my_foreign_type_get_int(value x);
bool my_foreign_type_get_bool(value x);
void my_foreign_type_set_bool(value x, bool b);
#703 is a new take on adding OCaml value in argument and result ocaml_value: string -> 'a typ. But it is more complicated than this one. However this one seems to put the address of the value in the fatptr which put the address in the nativeint. So the address of the value is outside the OCaml GC awarness, which is bad :wink: . Do you agree?