The issue is, I am not really sure what to put in the ( ??? ) part.
I have tried (coerce string (ptr uint8_t) (Bytes.unsafe_to_string out)), but this will not modify out, since (as far as I understand) strings are copied to outside of OCaml GC, and thus the shared ownership no longer exists.
My questions are
Is there a way to pass OCaml bytes directly to C functions?
Is there a way to pass OCaml string directly to C functions such that no copying is done?
You need to allocate CArrays or Bigbuffers and use them both for the input string and the mutable buffer, otherwise you will get in big troubles with the Gc. Look, for example, at: https://github.com/simonjbeaumont/ocaml-pci/pull/20 (if you use the latest ctypes this is even simpler as you can do CArray.of_string)
If you really want to reduce the number of copies and allocations, you are probably better off writing directly c stubs by hand, have a look at the “Interfacing with C” section of the ocaml manual. There you have String* and Bytes* accessors to read and write (directly I believe) in the ocaml strings. But double check the manual and read it carefully before believing me
of_string copies the data, since the memory representation of a string and a Bigarray.t are not the same.
However, since the memory representation of Bigarray is compatible with that of C arrays (using the correct layout), you can create a Bigarray from a C pointer using caml_ba_alloc. This will not incur any copying.
Unfortunately, I don’t know of any mechanism to convert a Bigarray from one kind to another, so I don’t know if you’d be able to use Bigstring, but if you create the Bigarray with the correct flags from the C side you can use the Int8_unsignedkind on the OCaml side.