Storing an OCaml value in a C structure

I have a C structure (rust, actually) that is manipulated in OCaml with normal stubs, with local parameters, etc. and so far, nothing unusual. The problem is that I want to store a record-of-functions inside this structure (callbacks), which I do by storing the value and declaring it as a global root using register_global_root. I remove the root when the structure is destroyed.

Now, when I call a C function on this structure, the C code will access a field of the value within, and use caml_callback<n>_exn to invoke the OCaml function in the stored record. So it’s caml->C->caml again on the stack. It works, until the inner OCaml code enters the GC, and then it gets stuck in an infinite loop in caml_oldify_local_roots () at roots.c:328. So my question is: is this use case supported, what is the proper discipline for the stubs in this case, and is *_global_root the proper way to store OCaml values in C?

5 Likes

The first thing that comes to mind, is that you should register not a global root, but a generational global root (see caml_register_generational_global_root). It might be a long shot, but this is what my intuition tells :slight_smile:

Also, for inspiration, and as a proof of concept, that you can actually store OCaml values in Rust runtime and live a happy life, consider looking into Bap’s Rust bindings. They are built on top of C-bindings which use Ctypes.Root.t (coupled with RTI for safe casting). In Rust OCaml values are stored in a RAII wrapper.

1 Like