将混合可存储向量传递给C函数

Sal*_*Sal 2 haskell ffi storable

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

我想弄清楚的是如何生成混合向量的向量(仅用于传递给C).我尝试了类似下面的玩具解决方案(它模拟相同的想法 - 生成Ptr混合类型的可存储向量- 在实际代码中,每个Ptr将指向另一个可存储向量).它因类型错误而失败 - 我怀疑它与之前在我之前提到的另一个问题中指出的存在性合格类型有关.由于我使用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 ()
Run Code Online (Sandbox Code Playgroud)

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.
Run Code Online (Sandbox Code Playgroud)

我将非常感谢如何解决上述问题.我可以使用Data.Vector.Storable.Mutable.new和unsafeWrite编写自定义矢量填充函数,但我仍然需要适合混合类型.

dfl*_*str 5

与在C中一样,您需要先将a char *和a转换int *为a,void *然后才能将其存储在通用数组中.所以,投你Ptr CCharPtr CInt一个Ptr ()将其插入载体之前.

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

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

voidPtr :: Ptr ()
voidPtr = castPtr intPtr
Run Code Online (Sandbox Code Playgroud)