2

我正在尝试使用 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

有关此错误的最佳解决方案的任何想法?我最初的想法是我需要使用unsafeForeignPtrToPtrto 转换为一个 foo 指针,但我不确定如何执行此操作/将其放入“包装器”的位置。

有什么线索吗?

4

1 回答 1

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
于 2016-02-13T03:35:46.950 回答