可存储的空数据声明

时间:2011-01-25 14:29:36

标签: haskell ghc ffi

我正在尝试为C库创建一个Haskell包装器。底层结构太复杂,不能表达为显式类型,除了在C函数之间传递之外,我实际上并没有使用它们,因此我使用EmptyDataDecls让GHC为我工作。

我需要的是指向其中一种数据类型的指针,但当我尝试使用alloca创建一个时,它会抱怨数据不属于Storable类型。例如:

{-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-}

module Main where

import Foreign.Marshal.Alloc
import Foreign.Ptr

data Struct

foreign import ccall "header.h get_struct"
    get_struct :: Ptr Struct -> IO ()

main = alloca $ \ptr -> get_struct ptr

GHC不会编译这个,说Storable Struct没有实例。我可以自己实现它:

instance Storable Struct where
    sizeOf _    = ...
    alignment _ = ...

但这接近于打败目的 - 如果我不关心结构中的内容,我不想定义这样的事情。

我注意到指向指针的指针工作正常,因为Ptr类是Storable。所以我可以在调用peek之前使用ptr get_struct来完成我的目标:

main = alloca $ \ptr -> do
  ptr <- peek ptr
  get_struct ptr

但这感觉就像是黑客。

有没有办法在不定义实例的情况下将空数据声明视为Storable

2 个答案:

答案 0 :(得分:6)

如果您不知道它有多大,就无法分配。该函数是否会忽略其参数?然后传入一个空指针。否则,你需要为结构实际分配足够的空间 - 不要通过分配零字节或指针大小的缓冲区来切角,因为被调用的函数将写入缓冲区的末尾,破坏内存。

完成数据声明,或编写具有适当大小和对齐值的Storable实例;没有办法以某种形式提供大小/对齐数据。

答案 1 :(得分:2)

这是另一种可能适合您的方法。我假设您可以访问定义需要分配的对象的所有C头文件。如果这是真的,你可以编写一层薄薄的C代码来分配和释放C对象。然后,您的Haskell代码可以调用这些C函数,而Haskell代码无需知道指针背后的内容。当Haskell的垃圾收集器知道不再需要对象时,Haskell也可以自动调用自由代码。

相关问题