[Haskell-cafe] [ANN] Haskell FFI Tutorial

Donn Cave donn at avvanta.com
Tue Nov 11 17:35:06 UTC 2014


quoth Evan Laforge <qdunkan at gmail.com>
...
> Yes, it would be safe to say that all haskell data types which are
> serializable to C should have only C types.  That also avoids the
> problem.  However, you have to convert between haskell and C at some
> point, and that means you wind up with C and haskell duplicates of all
> records, so each one is actually expressed in 3 places: the C struct,
> the haskell "CType" record, and the haskell type record.

That could happen ... I suppose there's no one way to do it that fits
every application, but often enough I can make do with the Haskell
"CTYpe" record, and it gives me a Storable value that has a valid type
enforced relationship to the C struct.  You wouldn't always need or
want a Haskell version of your C struct, per se, but if you do.

> Another reason you wind up with Storable instances of  non-CType
> records is Data.Vector.Storable.  It's very tempting to simply reuse
> that to pass to C, and maybe it's initially fine because it has Ints
> or Word32s or something "safe", but then one day 2 years later someone
> who doesn't know about that adds a Char field and now you're in
> trouble.

Data.Vector.Storable is a new one on me!  (I see it's in the non-portable,
experimental category, so it figures.)  The documentation I'm looking at
seems to be saying it wouldn't be "instantiated" for Char, though?

>> ypoke :: Char -> Char -> Char -> IO T
>> ypoke a b c = alloca $ \ tp -> do
>>         (#poke struct t, a) tp a
>>         (#poke struct t, b) tp b
>>         (#poke struct t, c) tp c
>>         peek tp
> 
> This is corrupting memory, since sizeOf 'c' == 4.  Like I said, it
> will probably look like it works because it's usually just overwriting
> adjacent fields or perhaps alignment padding or maybe it's "safe" if
> it's on the stack, but you are likely to get mysterious crashes under
> load.  Try changing the order of the pokes and see what happens.

Ah, you're right, a final poke to offset 0 overwrites everything.
In retrospect I ... don't know what I was thinking!

	Donn


More information about the Haskell-Cafe mailing list