I am making a simple wrapper for a c library that needs to have a list of vectors passed to it. It takes an array of pointers to arrays. To make a nice interface I’d like to have Vector (or list) of Vectors, but I can’t really find out how to do this in idiomatic haskell. (Or any other way than memcopying stuff around).
What I’m looking for is something like
Vector (Vector Foo) -> (Ptr (Ptr Foo) -> IO a) -> IO a
Edit: hCsound doesn’t deal with this exact case, so I’ve added a full example below.
You might want to look at my package hCsound (darcs repo), which has to deal with a very similar case.
Note that it’s very important that the C library doesn’t modify the arrays used by a
Data.Vector.Storable.Vector. If you do need to modify the data, you should copy the old data first, modify the array through the ffi, and finally wrap the pointers into a new Vector.Here’s the code. As was pointed out in a comment,
Data.Vector.Storable.Vectordoesn’t have a Storable instance itself, so you’ll need the outer vector to be aData.Vector.Vector.Note the array is allocated by
withArray, so it’s automatically gc’d after the function returns.These arrays aren’t null-terminated, so you’ll need to make sure that the length is passed to the C function by some other method.
withForeignPtrisn’t used. Instead,touchForeignPtris called to ensure that the ForeignPtr’s aren’t deallocated before the C function is finished. In order to usewithForeignPtr, you’d need to nest calls for each internal vector. That’s what thenestfunction in the hCsound code does. It’s rather more complicated than just callingtouchForeignPtr.