[Haskell-cafe] Help with c2hs, structs and typedefs?

Antoine Latter aslatter at gmail.com
Sun Mar 8 13:25:21 EDT 2009

Hey folks, I was trying to create some FFI bindings using c2hs and I
ran into trouble: I can't use the 'sizeof' and 'set' hooks for structs
that aren't defined inside a typedef.

I don't know a whole lot about C - is there any declaration I can make
to make something like my second struct work in c2hs?  Because the
second struct is what's provided in <sys/uio.h> :-)

In the following code, if you change all of the directives in the
haskell code from my_iovec_2 to my_iovec, the "unknown indentifier"
errors go away.



-- Works!
typedef struct {
 void * my_iov_base;
 int    my_iov_len;
} my_iovec;


-- Broken!  I get lots of "unknown identifier" errors for
-- the #sizeof and #set hooks - but the #pointer hook seems to work.
struct my_iovec_2 {
 void * my_iov_base;
 int    my_iov_len;

{#pointer *my_iovec_2 as IOVec newtype#}

withIOVec :: [(Ptr a, CSize)] -> (Ptr IOVec -> Int -> IO b) -> IO b
withIOVec [] f = f nullPtr 0
withIOVec bufers f
    = let len = length buffers in
      alocaBytes (length bufers * {#sizeof my_iovec_2#}) $ \ptr ->
      vecAry <- castPtr ptr
      foldM (go vecAry) 0 bufers
      f vecAry len

 where go vecAry off (ptr, size) = do
         vec <- vecAry `plusPtr` off * {#sizeof my_iovec_2#}
         {#set my_iovec_2->my_iov_base#} vec $ castPtr ptr
         {#set my_iovec_2->my_iov_len#}  vec $ cIntConv size
         return $ off + 1

More information about the Haskell-Cafe mailing list