Eddy JD
Eddy JD

Reputation: 73

Haskell FFI passing multiple arrays to C

I have a C function with type

int func(int len1, int *array1, int len2, int *array2);

that I'd like to call from Haskell. It doesn't modify its contents. I want to pass data from lists. I've been looking through Foreign.Marshal.Array, but I'm quite confused. Either newArray or withArray seems to do what I want, but withArray, for example, takes a function with type

Ptr a -> IO b

And I'm not quite sure how to deal with that given the two arrays in my function. So far, I have:

foreign import ccall unsafe "func.h func"
    c_func :: CInt -> Ptr CInt -> CInt -> Ptr CInt -> IO CInt

And I'm not sure how to call this. In the documentation (https://wiki.haskell.org/Foreign_Function_Interface#Arrays), it just says to read Foreign.Marshall.Array.

Thanks!

Edit: typo.

Upvotes: 2

Views: 263

Answers (1)

ephemient
ephemient

Reputation: 204698

The withArray* functions give you a Ptr within the scope of a function. You can write it as a lambda inline, like so:

func :: [CInt] -> [CInt] -> IO CInt
func list1 list2 =
    withArrayLen list1 $ \len1 array1 ->
      withArrayLen list2 $ \len2 array2 ->
        c_func (fromIntegral len1) array1 (fromIntegral len2) array2

You could also have computed the length separately, for example

func list1 list2 =
    withArray list1 $ \array1 ->
      withArray list2 $ \array2 ->
        c_func len1 array1 len2 array2
  where
    len1 = genericLength list1
    len2 = genericLength list2

Upvotes: 1

Related Questions