Haskell FFI调用C函数时capi模式传递指针值不符合预期问题
Haskell调用C函数
IupOpen出现指针类型不匹配警告问题 我尝试在Haskell侧调用如下声明的C函数:
int IupOpen(int *argc, char ***argv);
随后我编写了如下绑定代码:
foreign import capi "iup.h IupOpen" c_IupOpen :: Ptr CInt -> Ptr (Ptr CString) -> IO CInt iupOpen :: Maybe [String] -- ^ 程序命令行参数 -> IO Int -- ^ 初始化状态标志 iupOpen args = case args of Nothing -> fromIntegral <$> c_IupOpen nullPtr nullPtr Just argv -> alloca $ \argcPtr -> do poke argcPtr (fromIntegral . length $ argv) argvs <- mapM (`withCString` return) argv pCstr <- withArray argvs return argvPtr <- alloca $ \ppCstr -> poke ppCstr pCstr >> return ppCstr fromIntegral <$> c_IupOpen argcPtr argvPtr
编译后输出如下警告:
C:\...\AppData\Local\Temp\ghc6096_0\ghc_5.c: In function 'ghczuwrapperZC1ZChiupzm0zi1zi0zi0zm1ddNNYbMeka1JTSCkHxKK2ZCGraphicsziIUPziRawziIupZCIupOpen': C:\...\AppData\Local\Temp\ghc6096_0\ghc_5.c:10:143: warning: passing argument 2 of 'IupOpen' from incompatible pointer type [-Wincompatible-pointer-types] 10 | HsInt32 ghczuwrapperZC1ZChiupzm0zi1zi0zi0zm1ddNNYbMeka1JTSCkHxKK2ZCGraphicsziIUPziRawziIupZCIupOpen(void* a1, void*** a2) {return IupOpen(a1, a2);} | ^~ | | | void *** In file included from C:\...\AppData\Local\Temp\ghc6096_0\ghc_5.c:7: C:/.../hs/hs-iup/iup-3.30_Win64_mingw6_lib/include/iup.h:37:56: note: expected 'char ***' but argument is of type 'void ***' 37 | IUP_API int IupOpen (int *argc, char ***argv);
但我传入的参数argvPtr确实是Ptr (Ptr CString)类型,我不理解为何会出现该警告,希望得到相关解答。
更新1
经过尝试我将capi替换为ccall后解决了问题,看起来capi生成的包装函数没有使用正确的类型签名。但我仍然不理解capi为何无法正常工作,这是GHC的bug还是我遗漏了什么配置?
更新2
我修改了代码避免了悬空指针问题,修改后代码如下:
foreign import capi "iup.h IupOpen" c_IupOpen :: Ptr CInt -> Ptr (Ptr CString) -> IO CInt open :: Maybe [String] -- ^ 程序命令行参数 -> IO Int -- ^ 初始化状态标志 open args = case args of Nothing -> fromIntegral <$> c_IupOpen nullPtr nullPtr Just argv -> alloca $ \ptrArgc -> do poke ptrArgc (fromIntegral . length $ argv) alloca $ \ptrCStr -> do cstrArr <- mapM newCString argv -- 释放指针数组 pokeArray ptrCStr cstrArr alloca $ \pptrCStr -> do poke pptrCStr ptrCStr flag <- c_IupOpen ptrArgc pptrCStr mapM_ free cstrArr return . fromIntegral $ flag
但除非使用ccall,否则指针类型仍然不匹配。
更新3
最终我查询到这是GHC的已知bug,对应issue #15531。
内容的提问来源于stack exchange,提问作者Z-Y.L
相关产品推荐
相关产品推荐

