smilingbuddha smilingbuddha - 3 months ago 27
C Question

Passing struct-like data between C and Haskell via the FFI

Consider a Haskell data-type which looks like this

data MyData = MyData { arrInt :: [Int] , arrDouble :: [Double], arraySize :: N }


Here N represents the sizes of both the arrays the MyData record.

Is it possible to pass this (or some kind of Haskell "pointer" of a MyData object) to a C function which looks like this.

int myfunc (int* a, double* b, int N)


I am able to use the FFI to call C functions accepting and returning simple datat-types like Double, Int, Char etc. But for more complicated types I don't know what to do.

Answer

You could do something like that:

import Foreign
import Foreign.C

myfunc :: MyData -> IO CInt
myfunc d =
    withArray (map fromIntegral $ arrInt d) $ \arr1 ->
        withArray (map CDouble $ arrDouble d) $ \arr2 ->
            c_myfunc arr1 arr2 (fromIntegral $ arraySize d)

foreign import ccall c_myfunc :: Ptr CInt -> Ptr CDouble -> CInt -> IO CInt