# Ctypes pass OCaml bytes to C functions?

**URL:** <https://discuss.ocaml.org/t/ctypes-pass-ocaml-bytes-to-c-functions/2156>\
**Category:** Learning\
**Tags:** ctypes, ffi\
**Created:** [June 16, 2018, 10:10am UTC](https://discuss.ocaml.org/t/ctypes-pass-ocaml-bytes-to-c-functions/2156 "2018-06-16T10:10:23Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![darrenldl](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/darrenldl/32/291_2.png) [@darrenldl](https://discuss.ocaml.org/u/darrenldl)\
**Post date:** [June 16, 2018, 10:10am UTC](https://discuss.ocaml.org/t/ctypes-pass-ocaml-bytes-to-c-functions/2156/1 "2018-06-16T10:10:24Z")

</div>

Hello,

I’m trying to call a C function with roughly the following signature

```auto
int calc_stuff (const uint8_t* input, uint8_t* out);

```

It does some computation on the C side and writes to `out`.

I’m currently using Ctypes on the OCaml side, and have made roughly what follows

```auto
let calc_stuff =
  foreign "calc_stuff" (ptr uint8_t @-> ptr uint8_t -> returning int)

let calc (input: string) (out : bytes) : int =
  calc_stuff
    (coerce string (ptr uint8_t) input)
    ( ??? )

```

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

1. Is there a way to pass OCaml bytes directly to C functions?
2. Is there a way to pass OCaml string directly to C functions such that no copying is done?

Thanks in advance!

---

<div class="post-metadata">

**Author:** ![mseri](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mseri/32/91_2.png) [@mseri](https://discuss.ocaml.org/u/mseri)\
**Post date:** [June 16, 2018, 11:17am UTC](https://discuss.ocaml.org/t/ctypes-pass-ocaml-bytes-to-c-functions/2156/2 "2018-06-16T11:17:01Z")

</div>

You need to allocate `CArray`s or `Bigbuffer`s 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](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`)

Some brief information are also here: [https://github.com/ocamllabs/ocaml-ctypes/wiki/FAQ#strings](https://github.com/ocamllabs/ocaml-ctypes/wiki/FAQ#strings)

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

---

<div class="post-metadata">

**Author:** ![mseri](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mseri/32/91_2.png) [@mseri](https://discuss.ocaml.org/u/mseri)\
**Post date:** [June 16, 2018, 11:27am UTC](https://discuss.ocaml.org/t/ctypes-pass-ocaml-bytes-to-c-functions/2156/3 "2018-06-16T11:27:35Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![darrenldl](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/darrenldl/32/291_2.png) [@darrenldl](https://discuss.ocaml.org/u/darrenldl)\
**Post date:** [June 16, 2018, 4:43pm UTC](https://discuss.ocaml.org/t/ctypes-pass-ocaml-bytes-to-c-functions/2156/4 "2018-06-16T16:43:38Z")

</div>

Thanks very much for the reply!

I think I will migrate to using Bigarray to avoid things getting messy as multicore lands.

---

<div class="post-metadata">

**Author:** ![darrenldl](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/darrenldl/32/291_2.png) [@darrenldl](https://discuss.ocaml.org/u/darrenldl)\
**Post date:** [June 17, 2018, 4:32am UTC](https://discuss.ocaml.org/t/ctypes-pass-ocaml-bytes-to-c-functions/2156/5 "2018-06-17T04:32:35Z")

</div>

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

I intend to use

```auto
(int, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t

```

as it makes calculations easier at places, but `Bigstring` is

```auto
(char, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t

```

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`.

Thanks!

---

<div class="post-metadata">

**Author:** ![mseri](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mseri/32/91_2.png) [@mseri](https://discuss.ocaml.org/u/mseri)\
**Post date:** [June 17, 2018, 6:44am UTC](https://discuss.ocaml.org/t/ctypes-pass-ocaml-bytes-to-c-functions/2156/6 "2018-06-17T06:44:18Z")

</div>

I don’t have any experience with them, sorry. If you don’t get an answer here you can tryin the ocaml-ctypes mailing list

---

<div class="post-metadata">

**Author:** ![bcc32](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/bcc32/32/203_2.png) [@bcc32](https://discuss.ocaml.org/u/bcc32)\
**Post date:** [June 17, 2018, 6:36pm UTC](https://discuss.ocaml.org/t/ctypes-pass-ocaml-bytes-to-c-functions/2156/7 "2018-06-17T18:36:42Z")

</div>

> [@darrenldl](#):
>
> 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`](https://caml.inria.fr/pub/docs/manual-ocaml-4.06/libbigarray.html#sec565). This will not incur any copying.

> [@darrenldl](#):
>
> as it makes calculations easier at places, but `Bigstring` is
> 
> ```auto
> (char, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t
> 
> ```
> 
> and I cannot seem to find a function for converting between the two.

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_unsigned` _kind_ on the OCaml side.
