Is there a well-understood way to mix Ctypes.Foreign data structures with Ocaml C Stubs FFI? I am running into some corruption issues because I think I am doing this translation incorrectly.
Background:
I wrote kqueue bindings using Ctypes.Foreign, however due to some static linking reasons, I have decided to implement the bindings via classic Ocaml C FFI. I would like to continue to use Ctypes to generate bindings for the various structs and constants I need access to, for example the event list structure. Is it well-defined how to use a Ctypes ptr when calling Ocaml C FFI.
Here is the definition of my bindings:
I’m managing my event list via allocate_n
And I am trying to call it using with: (Ctypes.raw_address_of_ptr @@ Ctypes.to_voidp changelist.Eventlist.kevents)
And finally, I try to convert it back to the C representations with:
However, I seem to be getting some corruption at some point in running my program (note, this corruption has not been happening in running with Ctypes.Foriegn for several years, so it IS something to do with what I’m doing here).
I think I’m possibly seeing something around Garbage collection compaction? Although, I’m just guessing. The bad data looks like the following at the syscall level:
This is a helper function, not called directly from Ocaml, but from the C code Ocaml is calling. I believe I only have to do the OCaml FFI macros in the function that is being called directly.
Knock on wood, I think I found the solution. After digging around ctypes code it looks like it wraps points in a Fat pointer, which is really just a record with your Ocaml value in it + the pointer value. I’m running our test suite now and it seems to be working.