Hi everybody, I know this sounds like an issue many have faced before me, but good old google didn't come up with any helpful results. The basic problem is that I need to marshal a union so I can pass it to a C function via FFI. So to make sure I have my head wrapped around this correctly, say I have a union like so: typedef union { int i; char c; } my_union; This would typically be represented in Haskell as: data myUnion = I CInt | C CChar My question is how would you marshall (define an Storable instance for) myUnion into my_union? It's my understanding that an instance my_union would take up sizeof(int) bytes in memory, i.e. the size of it's largest member. So to store this we would write something along the lines of: instance Storable myUnion where size _ = #{size my_union} -- <-- hsc2hs shortcut alignment _ = alignment undefined::CInt -- <-- What should this really be? peek ptr = do -- <-- How are you supposed to know which element to extract? poke ptr (I i) = poke ptr i -- <-- Or should this be #{poke my_union, i} ptr i ? poke ptr (C c) = poke ptr c I hope this clear. I appreciate all the help. If this question has already been answered, which I'm sure it has, please point me to right spot. Thanks again for everyone's time. Nabil Alsharif.
On Wed, 13 Apr 2011, Nabil Alsharif wrote:
instance Storable myUnion where size _ = #{size my_union} -- <-- hsc2hs shortcut alignment _ = alignment undefined::CInt -- <-- What should this really be? peek ptr = do -- <-- How are you supposed to know which element to extract?
That's the great "feature" of C unions, that you cannot know that in general. You have to store somewhere else, in a boolean or flag set, whether the stored union value contains a 'char' or an 'int'.
poke ptr (I i) = poke ptr i -- <-- Or should this be #{poke my_union, i} ptr i ? poke ptr (C c) = poke ptr c
participants (2)
-
Henning Thielemann -
Nabil Alsharif