From mike at proclivis.com Wed Aug 6 21:51:10 2014 From: mike at proclivis.com (Michael Jones) Date: Wed, 6 Aug 2014 15:51:10 -0600 Subject: [C2hs] How to marshall variable length out array Message-ID: <3803815F-499A-4CDD-9A4E-BD4352108811@proclivis.com> I have an almost working marshaling of a C function and need help. The problem is the resulting hs does not pass the length to allocaArray and peekArray. What I want to happen is to use data_in_length to control the size of data created and peeked from. I am providing a hand adjusted hs to show what I want it to do, and asking if anyone knows how to write the hook to generate the small change. Note that the C is a wrapper around another library, so I can adjust the C signature if there is an easier signature structure to hook. Also note that data_in means data in from an I2C device. From the function point of view, it is really data being returned to the caller, where the caller specifies the amount of data requested. The C: int32_t ww_i2c_read_ext ( int32_t aardvark, uint16_t slave_addr, I2cFlags flags, uint8_t *data_in, uint16_t data_in_length, uint16_t *num_read The hook that is almost correct: {#fun unsafe ww_i2c_read as i2cRead {`Int', fromIntegral `CUShort', fromI2cFlags `I2cFlags', allocaArray- `[CUChar]' peekArray*, fromIntegral `CUShort'} -> `Int?#} The incorrect result: i2cRead :: Int -> CUShort -> I2cFlags -> CUShort -> IO (Int, [CUChar]) i2cRead a1 a2 a3 a5 = let {a1' = fromIntegral a1} in let {a2' = fromIntegral a2} in let {a3' = fromI2cFlags a3} in allocaArray $ \a4' -> let {a5' = fromIntegral a5} in i2cRead'_ a1' a2' a3' a4' a5' >>= \res -> peekArray a4'>>= \a4'' -> let {res' = fromIntegral res} in return (res', a4?') The manually fixed result that I want the hook to produce: i2cRead :: Int -> CUShort -> I2cFlags -> CUShort -> IO (Int, [CUChar]) i2cRead a1 a2 a3 a5 = let {a1' = fromIntegral a1} in let {a2' = fromIntegral a2} in let {a3' = fromI2cFlags a3} in allocaArray (fromIntegral a5) $ \a4' -> <>= \res -> peekArray (fromIntegral a5) a4'>>= \a4'' -> << ?????????????? pass size let {res' = fromIntegral res} in return (res', a4'')