我正在尝试使用c2hs包装C库。我有一个不透明的C结构,我在Haskell中映射如下:
{#pointer *foo as Foo foreign newtype #}
我使用了外部指针,因此我可以使用终结器自动清理。所有这一切似乎都很好。但是,我现在想要包装一个如下所示的函数指针:
typedef void (*hook_func)(foo *f, int a);
我的Haskell代码看起来像这样:
type HookFunc = Foo -> Int -> IO ()
foreign import ccall "wrapper"
mkHookFunc :: HookFunc -> IO (FunPtr HookFunc)
然而,当我编译时,我收到以下错误:
Unacceptable argument type in foreign declaration:
ForeignPtr Foo
有关此错误的最佳解决方案的任何想法?我最初的想法是,我需要使用unsafeForeignPtrToPtr
转换为foo指针,但我不知道如何做到/将它放在“包装器”中。
任何线索?
答案 0 :(得分:1)
我想我把它整理出来了。
我最终在gtk2hs中找到了一些类似于我想要的代码(https://github.com/gtk2hs/gtk2hs/blob/master/gio/System/GIO/Async/AsyncResult.chs)
我将回调定义为正常:
type HookFunc = Foo -> Int -> IO ()
然后我还定义了另一种使用Foreign.C
类型的类型,即
type CHookFunc = Foo -> CInt -> IO ()
然后包装器看起来像:
foreign import "wrapper"
mkHookFunc :: CHookFunc -> IO {# type hook_func_t #} -- hook_func_t is the typedef in the C header file
最后,我添加了一个编组功能,如下所示:
marshalHookFunc :: HookFunc -> IO {# type hook_func_t #}
marshalHookFunc hookFunc =
mkHookFunc $ \fooPtr i -> do
foo <- mkFoo fooPtr -- mkFoo constructs a ForeignPtr Foo out of a Ptr Foo
hookFunc foo i