Closed jmillikin closed 9 years ago
@jmillikin Yes, that was definitely broken by that change, and is clearly wrong. I'll look at it in the next couple of days. I fear there's going to be a bit of juggling needed to get all the combinations of these different things work -- that change fixed issue #115 which is closely related, but I obviously didn't do it quite right.
@jmillikin I believe that I've now fixed this (or at least made it less wrong). The generated code is different from before, but I think it's actually better. Here's an example. If you have the following C structure definition:
typedef struct {
int a[3]; /* An array of length 3. */
int *p; /* A pointer to an array. */
} array_t;
then the following C2HS code:
cInts <- mallocArray 3
pokeArray cInts [2, 4, 8]
{#set array_t->p#} myStruct cInts
p2 <- {#get array_t->p#} myStruct >>= peekArray 3
print p2
pokeArray cInts [3, 9, 27]
{#set array_t->a#} myStruct cInts
a2 <- {#get array_t->a#} myStruct >>= peekArray 3
print a2
produces this Haskell:
cInts <- mallocArray 3
pokeArray cInts [2, 4, 8]
(\ptr val -> do {pokeByteOff ptr 16 (val::(Ptr CInt))}) myStruct cInts
p2 <- (\ptr -> do {peekByteOff ptr 16 ::IO (Ptr CInt)}) myStruct >>= peekArray 3
print p2
pokeArray cInts [3, 9, 27]
(\ptr val -> do {copyArray (ptr `plusPtr` 0) (val::(Ptr CInt)) 3}) myStruct cInts
a2 <- (\ptr -> do {return $ ptr `plusPtr` 0 ::IO (Ptr CInt)}) myStruct >>= peekArray 3
print a2
Note the use of copyArray
for dealing with the array within the structure -- I think this a more correct solution than the use of poke
that was there before.
I'll close this for now, but feel free to reopen it if this doesn't solve your problem.
C struct definition:
.c2hs file contains:
c2hs 0.20.1 and earlier generate:
c2hs 0.21.1 and later generate:
This new generated code won't typecheck;
poke
isPtr a -> a -> IO ()
, sopoke ptr
is of typeCCharT -> IO ()
which obviously won't accept aCWString
.I believe this was caused by https://github.com/haskell/c2hs/commit/5698388cd4c4006dbcafe5dba7fcd2769f920d69