在FFI可以处理数组?如果是这样,怎么样? [英] Can the FFI deal with arrays? If so, how?

查看:591
本文介绍了在FFI可以处理数组?如果是这样,怎么样?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是pretty相信这是可能通过FFI发送阵列,但我找不到任何的例子。举例来说,我有一个Haskell数组,我发送到 INT美孚(INT *)函数,或者我有一个C数组 INT条[64 ]; 我发送给哈斯克尔

I'm pretty sure it's possible to send arrays through the FFI, but I can't find any examples. For instance, I have a Haskell array that I send to a int foo(int*) function, or I have a C array int bar[64]; that I send to Haskell.

在理想情况下我会想最有效的方式 - 我不希望任何堆分配或不必要的复制。此外,这将是很好,如果我可以使用Haskell的拆箱阵列在这两个Haskell和C.那么什么是这样做的方法是什么?

Ideally I'd want the most efficient way - I don't want any heap allocation or unnecessary copying. Also, it would be nice if I could use Haskell's unboxed arrays in both Haskell and C. So what's the method of doing so?

推荐答案

如果你使用,你可以使用Data.Vector.Storable您需要的Data.Vector库。然后你可以使用的功能,如unsafeToForeignPtr或unsafeWith访问底层外指针。这使您可以拨打C- code没有任何复制或编组的发生。

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.

如果您要创建从C阵列向量可以使用unsafeFromForeignPtr。

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

有关你的例子,你可以使用(假设c_foo不会修改它的参数)

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

import Foreign.Ptr
import Foreign.C.Types
import System.IO.Unsafe (unsafePerformIO)
import qualified Data.Vector.Storable as SV

foreign import ccall unsafe "foo" c_foo :: Ptr CInt -> CInt

haskellFoo :: SV.Vector CInt -> CInt
haskellFoo sv = unsafePerformIO $
    SV.unsafeWith sv $ \ptr -> return (c_foo ptr)

这可以被golfed为:

This can be be golfed to:

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

请注意,如果你的C函数修改了数据,那么你不应该这样做,相反,你应该
使数据的副本,不会打破引用透明。

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

如果你想使用标准的数组类型你可以使用 withStorableArray Data.Array.Storable 中一样的方法。

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

这篇关于在FFI可以处理数组?如果是这样,怎么样?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆