Can the FFI deal with arrays? If so, how? Can the FFI deal with arrays? If so, how? arrays arrays

Can the FFI deal with arrays? If so, how?


If you use the Data.Vector library you could use Data.Vector.Storable for your needs. Then you can use functions such as unsafeToForeignPtr or unsafeWith to access the underlying foreign pointer. This allows you to call C-code without any copying or marshaling taking place.

If you want to create a vector from a C-array you can use unsafeFromForeignPtr.

For your examples you can use (assuming c_foo does not modify it's arguments)

import Foreign.Ptrimport Foreign.C.Typesimport System.IO.Unsafe (unsafePerformIO)import qualified Data.Vector.Storable as SVforeign import ccall unsafe "foo" c_foo :: Ptr CInt -> CInthaskellFoo :: SV.Vector CInt -> CInthaskellFoo sv = unsafePerformIO $    SV.unsafeWith sv $ \ptr -> return (c_foo ptr)

This can be be golfed to:

haskellFoo sv = unsafePerformIO $    SV.unsafeWith sv (return . c_foo)

Note that if your C-function modifies the data, then you shouldn't do this, instead you shouldmake a copy of the data to not break referential transparency.

If you want to use the standard Array-type you could use withStorableArray from Data.Array.Storable in the same way.


The FFI specification is quite readable, so you might want to just sit down and work through the whole thing. However, for this specific question, you can jump to the "Marshalling" section, particularly the Ptr and Storable subsections, which outline what's available for this.


To convert a FFI Ptr into a Haskell list, you can use:

peekArray0 :: (Storable a, Eq a) => a -> Ptr a -> IO [a]

http://hackage.haskell.org/packages/archive/base/4.2.0.1/doc/html/Foreign-Marshal-Array.html#v%3ApeekArray0