c - Haskell FFI 关于双指针参数的问题

标签 c haskell ffi

我正在尝试绑定(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/

相关文章:

c - luaL_openlibs 的隐式声明

c - 添加更多线程在什么时候停止帮助?

c - 使用 GNU Autotools 获取 GCC 包含路径

haskell - double 类型

Haskell 在奇怪的地方抛出解析错误

c - 找出具有素数因数的数字的个数

haskell - 什么算作副作用?为什么内存分配不是副作用?

linux - 为读取系统调用编写 Haskell FFI

javascript - PureScript 乘积和类型上的 JS 模式匹配

ncurses - native 调用接口(interface) : how to translate "wchar_t"?