6

Data.Vector.Storableがその要素を連続したメモリ領域に格納することを読みました。私はそれが関数VectorのインスタンスであるForeign.Storableか、少なくとも関数があることを期待していましたが、存在するの:: Vector a -> Ptr (Vector a)は。だけunsafeToForeignPtr0 :: Storable a => Vector a -> (ForeignPtr a, Int)です。

私のHaskellコードはForeign.Storable物事のリストを生成し、Cコードからこのリストにアクセスしたいと思います。これを行うのに適切なデータ型ですかVector.Storable?はいの場合、C側からその要素にどのようにアクセスする必要がありますか?

4

2 に答える 2

4

Cからメモリを変更しない場合は、を使用できますunsafeWith。Cから変更を加える必要がある場合は、最初にベクトルをコピーするか、C側でコピーを作成できます。(Cから変更する必要があるが、Haskell側のデータが不要になった場合は、unsafeWithコピーせずに使用することもできますが、ベクトルが二度と使用されないようにする必要があります。これにより、トリッキーで、怠惰とすべてで...)

では、なぜいつVector aのインスタンスではないのですか?ええと、一つには:ベクトルはどうあるべきですか?その関数には署名がありますが、ドキュメントには「引数は使用されていません」と記載されていることを思い出してください。うまくいけば、内部を知っている誰かがやって来て、信頼できる答えを出しますが、私が知る限り、すべてのインスタンスは「固定サイズ」タイプです。StorableasizeOf(Storable a) => a -> IntStorable

補遺:要求している関数シグネチャは実際には意味がありません。あなたが持っていたとしfoo :: Vector a -> Ptr (Vector a)たら、それは本当に意味がありfoo (fromList [1,2]) == foo (init (fromList [1,2,3]))ますか?これらは現在ポインタであり、非常に異なる可能性があることを忘れないでください。

于 2013-01-02T16:39:42.523 に答える
1

考えられる解決策:

import qualified Foreign.Ptr as P
import qualified Data.Vector.Storable as SV
import qualified Data.Vector.Storable.Internal as SVI
import qualified GHC.ForeignPtr as FP

ptr0ToVector :: SV.Storable a => P.Ptr a -> Int -> IO (SV.Vector a)
ptr0ToVector ptr size =
 FP.newForeignPtr_ ptr >>= \foreignPtr ->
 return (SV.unsafeFromForeignPtr0 foreignPtr size)

vectorToPtr0 :: SV.Storable a => SV.Vector a -> (P.Ptr a,Int)
vectorToPtr0 vector =
 let (foreignPtr,size) = SV.unsafeToForeignPtr0 vector
 in (SVI.getPtr foreignPtr,size)
于 2013-10-31T16:07:30.097 に答える