矢量(矢量Foo)-> (Ptr(Ptr Foo)->IO a)->奥一个?
我正在为 ac 库制作一个简单的包装器,需要将向量列表传递给它。它需要一个指向数组的指针数组。为了制作一个漂亮的界面,我想要向量(或向量列表),但我无法真正找到如何在惯用的 haskell 中做到这一点。 (或者除了内存复制之外的任何其他方式)。
我正在寻找的是类似的东西
Vector (Vector Foo) -> (Ptr (Ptr Foo) -> IO a) -> IO a
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
由于您要传递给 C 函数,因此应该使用
Data.Vector.Storable
。您不能只传递Storable
的向量,因为这不仅仅是指向数组的指针的向量,它还包含大小和偏移量信息。如果 C 函数的参数是 int myCFunc(foo** arrays, int sz) ,那么下面的代码应该可以工作:
Since you're passing to a C function, you should use
Data.Vector.Storable
. You can't just pass a vector of vectors ofStorable
because that will not be a vector merely of pointers to arrays, it also includes size and offset information.if the argument to the C function is, say,
int myCFunc(foo** arrays, int sz)
then the following code should work:编辑:hCsound 不处理这种确切的情况,所以我在下面添加了一个完整的示例。
您可能想查看我的包 hCsound (darcs repo),它必须处理非常相似的情况。
请注意,C 库不会修改
Data.Vector.Storable.Vector
使用的数组,这一点非常重要。如果确实需要修改数据,则应先复制旧数据,通过ffi修改数组,最后将指针包装到新的Vector中。这是代码。正如评论中指出的那样,Data.Vector.Storable.Vector 本身没有 Storable 实例,因此您需要将外部向量设为 Data.Vector.Vector 。
请注意,该数组是通过
withArray
分配的,因此在函数返回后会自动进行 gc'd。这些数组不是以 null 终止的,因此您需要确保通过其他方法将长度传递给 C 函数。
未使用
withForeignPtr
。相反,会调用touchForeignPtr
以确保在 C 函数完成之前不释放ForeignPtr。为了使用withForeignPtr
,您需要为每个内部向量嵌套调用。这就是 hCsound 代码中的nest
函数的作用。它比仅仅调用touchForeignPtr
复杂得多。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.Vector
doesn'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.
withForeignPtr
isn't used. Instead,touchForeignPtr
is 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 thenest
function in the hCsound code does. It's rather more complicated than just callingtouchForeignPtr
.