[Haskell-cafe] accessing a ByteArray from FFI

Mihaly Barasz klao at nilcons.com
Wed Jun 25 12:54:24 UTC 2014

On Wed, Jun 25, 2014 at 2:11 PM, Johan Tibell <johan.tibell at gmail.com> wrote:
> Hi,
> On Wed, Jun 25, 2014 at 12:58 PM, Mihaly Barasz <klao at nilcons.com> wrote:
>> 1. Is this actually OK to do? I guess that this wouldn't be OK if the
>> foreign import were "safe", as then the GC could move the contents of
>> the byte array while the foreign function is running. But is it safe
>> like this?
> Whether the foreign import is marked as safe or not doesn't matter. The GC
> might move the array just after you make your address computation but before
> the call is made. This is only safe if the Primitive array is guaranteed to
> be pinned. I checked the docs for that module and couldn't see any such
> promise.

Well, I don't know enough about how GC is specified in GHC, but _in
practice_ calls to GC could happen only on entry to the exampleFn
closure.  Not between the address computation and the foreign call. (I
simply looked at the generated code, I don't know if there is any
guarantee for that.)

>> 2. If the answer to the previous question is no, then is there a way to
>> do it properly? Or there is just no way to pass an unpinned byte array
>> to a foreign call? What about foreign import prim?
> There is a way to pass an unpinned ByteArray# (or MutableByteArray#, but the
> former seems right in your case) to a foreign call, using the
> UnliftedFFITypes language extension. The ByteArray# is guaranteed to not to
> be moved for the duration of the call. The code should treat the ByteArray#
> argument as if it was a pointer to bytes. You will need to do any address
> offset computations on the C side (i.e. pass any offsets you need as extra
> argument to your C function).

Thanks, I'll look into that. Are there any pointers/examples?

>> 3. If the answer to Q1 is no, then would it be OK if the underlying byte
>> array were pinned?
> Yes, but I don't know if you can have the API give you any such guarantees,
> unless you use the Storable vector version.
>> 4. Any other simplifications?
> The unsafeThat bothers me. Doesn't vector give you any other way to get to
> the underlying ByteArray#?

I don't know why, but the constructor for Vector is not exported, only
for the MVector. But, this use of unsafeThaw is completely benign.
(Actually, it fully disappears in the generated code. :))

> -- Johan

More information about the Haskell-Cafe mailing list