数组 – 带有C struct指针/数组字段的Haskell Data.Vector.Stora
我正在使用带有C库的
Haskell FFI,它定义了许多结构类型,这些结构类型包含指向双精度的成员,旨在被视为双精度数组:
typedef struct Foo { int length; double* values; } FooT; 在我对这个库的Haskell绑定中,我有一个等效的数据类型,我正在尝试使用Data.Vector.Storable.Vector Double作为数组: data Foo = Foo { length :: Int,values :: Data.Vector.Storable.Vector Double } deriving (Show,Eq) 当然,为了在C库和我的Haskell代码之间编组数据,我必须为这些类型编写可存储的实例.我正在尝试使用Data.Vector.Storable.unsafeFromForeignPtr来从C库已分配并填充在堆上的double *数组创建Haskell Vectors.我希望通过这样做我可以避免复制double *数组的内容,只需将Vector作为数组的一种包装器. (旁边的问题是:假设双*阵列可以达到10,000s的双倍,是否值得追求这种非复制?) 这就是我到目前为止所拥有的.我正在使用hsc2hs宏来帮助生成可存储的peek实现: instance Storable Foo where alignment _ = alignment (undefined :: CDouble) sizeOf _ = #{size FooT} peek ptr = do len <- (#peek FooT,length) ptr valuesField <- ((#peek FooT,values) ptr) :: IO (ForeignPtr Double) let values' = DV.unsafeFromForeignPtr0 valuesField len return Foo { length = len,values = values' } poke ptr (Foo len values') = do (#poke FooT,length) ptr len DV.unsafeWith values' (ptrValues -> (#poke FooT,values) ptr ptrValues) 所以在我看来,我正在尝试将值成员#peek作为ForeignPtr Double,然后我可以将其与unsafeFromForeignPtr一起使用.但是,#peek会生成如下代码: valuesField <- ((( hsc_ptr -> peekByteOff hsc_ptr 16)) ptr) :: IO (ForeignPtr Double) 因为ForeignPtr Double没有可存储的实例而被卡住了.我想如果我试图为ForeignPtr Double实现一个实例,我只是将如何访问struct成员的地址值的问题转换为该实例的peek实现. 总而言之,如何以这样的方式访问地址值(即指针)struct成员,以便将其用作unsafeFromForeignPtr的参数? 解决方法
我不知道如何使用hsc2hs,但你已经有了一个指向数据的指针,所以你只需要使用它,当然要有适当的偏移量.免责声明:此编译,但未经测试.
import Data.Vector.Storable (Vector,unsafeFromForeignPtr) import Foreign.Storable (Storable (..)) import Foreign.C.Types import Foreign.ForeignPtr (newForeignPtr_) import Foreign.Ptr instance Storable Foo where peek ptr = do len <- peek (castPtr ptr) valsPtr <- newForeignPtr_ (castPtr ptr `plusPtr` (sizeOf (undefined :: CInt))) return $Foo len $unsafeFromForeignPtr valsPtr 0 len (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |