Marshalling C unions

Nabil Alsharif <[email protected]> Wed, 13 Apr 2011 12:29:39 -0500
Newsgroups gmane.comp.lang.haskell.ffi
Message-ID <[email protected]>
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.