我正在尝试绑定(bind)到外部 C 库中的 C 函数,该函数返回指向内存缓冲区的指针和缓冲区的长度:
extern int myfunc(int arg1, unsigned char **buffer, size_t *buffer_len);
我尝试了以下代码,但结果出现段错误。
{-# LANGUAGE ForeignFunctionInterface #-}
import Foreign
import Foreign.C.Types (CInt(..), CUChar(..), CSize(..))
import Foreign.Ptr (Ptr)
import Foreign.Marshal.Array (peekArray)
foreign import ccall unsafe "myfunc" c_myfunc :: CInt -> Ptr (Ptr CUChar) -> Ptr CSize -> IO (CInt)
getBuffer :: Int -> IO [CUChar]
getBuffer arg1 = do
alloca $ \buffer -> do
alloca $ \buflen -> do
res <- c_myfunc (CInt arg1) buffer buflen
buflen' <- fromIntegral <$> peek buflen
cs <- peekArray buflen' buffer -- return a [Ptr CUChar] of size buflen
cs' <- mapM peek cs -- return a [CUChar] of size buflen
return cs'
我假设 peekArray 确实分配了足够的内存,所以我不确定它哪里出了问题。欢迎任何帮助。
最佳答案
愚蠢的错误,我错过了取消引用步骤。此代码现在可以运行:
{-# LANGUAGE ForeignFunctionInterface #-}
import Foreign
import Foreign.C.Types (CInt(..), CUChar(..), CSize(..))
import Foreign.Ptr (Ptr)
import Foreign.Marshal.Array (peekArray)
foreign import ccall unsafe "myfunc" c_myfunc :: CInt -> Ptr (Ptr CUChar) -> Ptr CSize -> IO (CInt)
getBuffer :: Int -> IO [CUChar]
getBuffer arg1 = do
alloca $ \ ptrbuf -> do
alloca $ \buflen -> do
res <- c_myfunc (CInt arg1) ptrBuf buflen
buflen' <- fromIntegral <$> peek buflen
buffer <- peek ptrBuf -- I MISSED THIS ONE. Extra dereferencing needed.
peekArray buflen' buffer -- return a [CUChar] of size buflen'
关于c - Haskell FFI 关于双指针参数的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34507373/