2

我有一个向量列表 - 类型集是已知且固定的 - 让我们说,CInt并且CChar. 该列表在编译时是未知的 - 组成将在运行时从配置文件中确定。例如,我们可能决定需要将两个向量传递给C函数:一个CInt长度为 10 的CChar向量,一个长度为 50 的向量。至于 C 函数如何解释它们,我可以通过传递一个向量编码每个向量的类型来处理该逻辑 (比如说,0 => CInt, 1 => CChar),以及传递的每个向量的向量编码长度 (10,50)。

我想弄清楚的是如何生成混合向量的向量(仅用于传递给C)。我尝试了一个像下面这样的玩具解决方案(它模拟了相同的想法 - 生成Ptr混合类型的可存储向量 - 在实际代码中,每个 Ptr 将指向另一个可存储向量)。由于类型错误而失败 - 我怀疑它与 ehird 之前在我之前提出的另一个问题中指出的存在限定类型有关。由于我使用 Storable 实例传递给 C FFI,我想我无法包装类型(不定义另一个可存储实例)。

{-#  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 中一样,您需要将 achar *int *a 转换为 avoid *才能将其存储在通用数组中。因此,在将其插入向量之前将其转换为Ptr CChara Ptr CIntPtr ()

您可以使用如下Foreign.Ptr.castPtr函数转换指针:

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

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