【问题标题】:Passing mixed storable vectors to a C function将混合可存储向量传递给 C 函数
【发布时间】:2012-02-07 18:47:12
【问题描述】:

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

我想弄清楚的是如何生成混合向量的向量(仅用于传递给 C)。我尝试了一个类似下面的玩具解决方案(它模拟了相同的想法 - 生成混合类型的Ptr 的可存储向量 - 在实际代码中,每个 Ptr 将指向另一个可存储向量)。由于类型错误而失败 - 我怀疑它与 ehird 之前在我之前问过的另一个 question 中指出的存在限定类型有关。由于我使用 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 编写自定义向量填充函数,但我仍然需要适应混合类型。

【问题讨论】:

    标签: haskell ffi storable


    【解决方案1】:

    就像在 C 中一样,您需要将 char *int * 转换为 void *,然后才能将其存储在通用数组中。因此,将您的 Ptr CCharPtr CInt 转换为 Ptr (),然后再将其插入向量中。

    您可以像这样使用Foreign.Ptr.castPtr 函数来转换指针:

    intPtr :: Ptr CInt
    intPtr = undefined -- dummy value
    
    voidPtr :: Ptr ()
    voidPtr = castPtr intPtr
    

    【讨论】:

      猜你喜欢
      • 2011-12-02
      • 1970-01-01
      • 1970-01-01
      • 2015-08-07
      • 2016-04-20
      • 1970-01-01
      • 1970-01-01
      • 2020-12-26
      • 2011-09-15
      相关资源
      最近更新 更多