Edit: hCsound does not deal with this exact case, so I added a complete example below.
You might want to check out my hCsound package ( darcs repo ), which should deal with a very similar case.
Please note that it is very important that the C library does not Data.Vector.Storable.Vector arrays used by Data.Vector.Storable.Vector . If you need to change the data, first copy the old data, change the array via ffi, and finally wrap the pointers in a new vector.
Here is the code. As noted in the comment, Data.Vector.Storable.Vector does not have an instance of Storable, so you need the external vector to be Data.Vector.Vector .
import Foreign.Storable import Foreign.Ptr import Foreign.ForeignPtr import Foreign.Marshal.Array import qualified Data.Vector as V import qualified Data.Vector.Storable as S import Data.Vector.Storable.Internal withPtrArray vf = do let vs = V.map S.unsafeToForeignPtr v -- (ForeignPtr, Offset, Length) ptrV = V.toList $ V.map (\(fp,off,_) -> offsetToPtr fp off) vs res <- withArray ptrV f V.mapM_ (\(fp,_,_) -> touchForeignPtr fp) vs return res
Note that the array is allocated withArray , so it is automatically gc'd after the function returns.
These arrays do not end in zero, so you need to make sure that the length is passed to the C function by some other method.
withForeignPtr not used. Instead, touchForeignPtr is touchForeignPtr to ensure that ExternalPtr is not freed until function C is completed. To use withForeignPtr , you will need to call calls for each internal vector. This is what the nest function does in hCsound code. This is more complicated than just calling touchForeignPtr .
source share