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)
I have been planning on writing a blog post on that and other issues that we have ecountered in dealing with strings and ctypes bindings… I should do it sooner rather than later
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
@mseri Do you happen to also know if Bigstring.of_string and Bigstring.to_string are doing anything special for quickly constructing the internal Bigarray and string or is it just copying?
and I cannot seem to find a function for converting between the two.
Just trying to figure out if there is any performance difference between Bigstring.of_string and just copying it into the (int, _, _) Bigarray.Array1.t.
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.