我是Haskell编程,外部函数接口和Stackoverflow的新手。我正在尝试为基于C的库构建一个Haskell FFI绑定。请找一个假设的例子,这是非常相似,我现在的问题如下:Haskell FFI - mallocForeignPtr用法
考虑我有一个C结构和功能是这样的:
typedef struct {
int someInt;
void *someInternalData;
} opaque_t;
int bar (opaque_t *aPtr, int anArg);
不透明的C结构是这里的out参数。我应该将其传递给其他API。调用者不需要去引用不透明的结构体。
查找下面myFFI.hsc文件与FFI进口:
{-# LANGUAGE CPP, ForeignFunctionInterface #-}
module MyFFI where
import Foreign
import Foreign.Ptr
import Foreign.ForeignPtr
import Foreign.C.Types
import Foreign.C
import System.IO.Unsafe
import Foreign.Marshal
import qualified Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
import qualified System.IO (putStrLn)
#include "myclib.h"
newtype OpaquePtr = OpaquePtr (ForeignPtr OpaquePtr)
#let alignment t = "%lu", (unsigned long)offsetof(struct {char x__; t (y__); }, y__)
instance Storable OpaquePtr where
sizeOf _ = #{size opaque_t}
alignment _ = #{alignment opaque_t}
peek _ = error "Cant peek"
foreign import ccall unsafe "myclib.h bar"
c_bar :: Ptr OpaquePtr
-> CInt
-> CInt
barWrapper :: Int -> (Int, ForeignPtr OpaquePtr)
barWrapper anArg = System.IO.Unsafe.unsafePerformIO $ do
o <- mallocForeignPtr
let res = c_bar (fromIntegral anArg) (Foreign.ForeignPtr.Unsafe.unsafeForeignPtrToPtr o)
return ((fromIntegral res), o)
在我实际的代码,类似于执行上述似乎工作。但是当我传递不透明的结构参考时,我得到了奇怪的输出,有时候ghci会激化。
我不确定在FFI调用中使用mallocForeignPtr和ForeignPtr。对于漫长的生活参考,我们应该使用ForeignPtr + mallocForeignPtr,但是我们无法在ccall中传递一个ForeignPtr。那么怎么做呢?我的上述逻辑正确吗? 任何形式的帮助都会非常棒。谢谢。