ocaml-ctypes icon indicating copy to clipboard operation
ocaml-ctypes copied to clipboard

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

Open mrmr1993 opened this issue 5 years ago • 1 comments

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 typ constructor Value, 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 typ for the value
    • the type is deliberately abstract, so that there is still some discipline enforced around distinct types being kept separate
  • adds a few small tests, namely a intnat clone 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);

mrmr1993 avatar Oct 22 '20 05:10 mrmr1993

#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?

bobot avatar Jan 13 '22 17:01 bobot