2012-02-07 11 views
2

私はベクターのリストを持っています - タイプのセットは既知で固定です - CIntCCharと言いましょう。リストはコンパイル時には不明です。構成は実行時に構成ファイルから決定されます。例えば、C関数に2つのベクトルを渡す必要があると決めるかもしれません:1つのCIntベクトル長10、1つはCChar長さ50のベクトルです。C関数がそれらをどのように解釈するかについては、各ベクトル(例えば、0 =>CInt,1 =>CChar)と、渡される各ベクトルの長さを符号化するベクトル(10,50)とを含む。C関数に保存可能なベクトルを渡す

私が理解しようとしているのは、(Cに渡す)混合ベクトルのベクトルを生成する方法です。私は以下のようなおもちゃのソリューションを試しました(実際のコードでは、別のStorableベクトルを指し示す、実際のコードでは、同じ考えをモデル化して、混合型のPtrの保存可能なベクトルを生成しています)。それは型エラーのために失敗しました - 私は先に質問した別のquestionの中に先に指摘された実在の修飾型に関係していると思われます。私はC FFIに渡すためにStorableインスタンスを使用しているので、(別の格納可能なインスタンスを定義することなく)型をラップすることはできないと思います。 GHCiの7.4.1で

{-# LANGUAGE BangPatterns, GADTs #-} 
import Data.Vector.Storable as SV 
import Foreign.C.Types (CChar, CInt) 
import GHC.Int (Int32) 
import Foreign.Marshal.Alloc 
import Foreign.Ptr (Ptr) 

mallocInt :: IO (Ptr CInt) 
mallocInt = malloc 

mallocChar :: IO (Ptr CChar) 
mallocChar = malloc 

main = do 
    a <- mallocInt 
    b <- mallocChar 
    let c = SV.fromList [a,b] 
    return() 

エラー:

test.hs:17:26: 
    Couldn't match expected type `CInt' with actual type `CChar' 
    Expected type: Ptr CInt 
     Actual type: Ptr CChar 
    In the expression: b 
    In the first argument of `fromList', namely `[a, b]' 
Failed, modules loaded: none. 

私は上記の問題を解決する方法についてのポインタを感謝します。私は、Data.Vector.Storable.Mutable.newとunsafeWriteを使用してカスタムのベクトル塗りつぶし関数を書くことができましたが、混合型に合わせる必要があります。

答えて

5

Cと同様に、char *int *void *にキャストしてから、ジェネリックアレイに格納する必要があります。したがって、Ptr CCharとをPtr()にキャストしてからベクターに挿入してください。

あなたはそうのようなForeign.Ptr.castPtr機能を使って、ポインタをキャストすることができます

intPtr :: Ptr CInt 
intPtr = undefined -- dummy value 

voidPtr :: Ptr() 
voidPtr = castPtr intPtr 
+0

あなたもしてもらえHaskellでは 'のPtr()'に 'のPtr CChar'をキャストする方法の例を示して? Unsafecoerceを使用しますか? – Sal

+0

@sal、確かな事!いくつかのサンプルコードを追加しました。 – dflemstr

+0

非常に感謝します。 – Sal