yallop / ocaml-ctypes

Library for binding to C libraries using pure OCaml
MIT License
363 stars 95 forks source link

Add support for C functions which directly handle OCaml `value`s #659

Open mrmr1993 opened 3 years ago

mrmr1993 commented 3 years ago

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

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);
bobot commented 2 years ago

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?