通过FFI导出/导入与使用FFI包装器

时间:2017-12-02 16:27:13

标签: haskell function-pointers ffi

我使用以下习语继承了代码库,该代码库通过FFI导出然后重新导入函数:

foreign export ccall someHaskellFn :: a -> IO b
foreign import ccall "&someHaskellFn"
  someHaskellFn_addr :: FunPtr (a -> IO b)

Haskell函数someHaskellFn和导出的函数都没用过;只需要someHaskellFn_addr,并且始终在IO上下文中使用:

-- frob :: FunPtr (a -> IO b) -> IO ()
frob someHaskellFn_addr

我想知道这是否比使用包装器功能有任何优势:

foreign import ccall "wrapper"
  mkWrapper :: (a -> IO b) -> IO (FunPtr (a -> IO b))

-- Function pointer to someHaskellFn, never freed
someHaskellFnPtr = mkWrapper someHaskellFn
frob =<< someHaskellFnPtr

Foreign.Ptr的文档提到了这两种方法来创建FunPtr a类型的值:

  

FunPtr类型的值可以是指向外部函数的指针,   要么由另一个外国函数返回,要么用a导入   静态地址导入,如

foreign import ccall "stdlib.h &free"
  p_free :: FunPtr (Ptr a -> IO ())
     

或指向使用包装器存根创建的Haskell函数的指针   声明生成一个正确类型的FunPtr。

它也说

  

调用包装器存根[...]分配存储,当不再需要时,应该使用freeHaskellFunPtr释放存储。

我的理解是使用代码的包装器表现为导出/导入变体的(在Haskell端)。它是否正确?有没有关于我缺少的外国功能进口和出口的更详细信息?

0 个答案:

没有答案