2

私はベクトルのリストを持っています-タイプのセットは既知で固定されています-としましょう、CIntそしてCChar。このリストはコンパイル時には不明です。構成は実行時に構成ファイルから決定されます。たとえば、C関数に2つのベクトルを渡す必要があると判断する場合があります。1つCIntは長さ10のCCharベクトル、もう1つは長さ50のベクトルです。C関数がそれらを解釈する方法については、各ベクトルのベクトルエンコードタイプを渡すことでそのロジックを処理できます(たとえば、0 => CInt、1 => CChar)、および渡された各ベクトルのベクトルエンコード長(10,50)。

私が理解しようとしているのは、混合ベクトルのベクトルを生成する方法です(Cに渡すためだけに)。私は以下のようなおもちゃの解決策を試しました(Ptr実際のコードでは、同じアイデアをモデル化して、混合タイプの保存可能なベクトルを生成します。各Ptrは別の保存可能なベクトルを指します)。型エラーのために失敗しました-以前に尋ねた別の質問でehirdが以前に指摘した存在修飾型に関連していると思われます。C FFIに渡すためにStorableインスタンスを使用しているので、(別の保存可能なインスタンスを定義せずに)型をラップすることはできないと思います。

{-#  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 ()

ghci 7.4.1のエラー:

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を使用してカスタムのベクトル入力関数を作成することもできますが、それでも混合型を適合させる必要があります。

4

1 に答える 1

5

Cの場合と同様に、ジェネリック配列に格納する前に、char *とをにキャストする必要があります。したがって、ベクトルに挿入する前に、とをにキャストします。int *void *Ptr CCharPtr CIntPtr ()

Foreign.Ptr.castPtr次のような関数を使用して、ポインタをキャストできます。

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

voidPtr :: Ptr ()
voidPtr = castPtr intPtr
于 2012-02-07T19:02:53.123 に答える