我正在尝试从Real World Haskell编写一个示例(第26章):
我想使用C
调用FFI
函数:
#include <stdint.h>
#include <sys/types.h>
/* only accepts uint32_t aligned arrays of uint32_t */
void hashword2(const uint32_t *key, /* array of uint32_t */
size_t length, /* number of uint32_t values */
uint32_t *pc, /* in: seed1, out: hash1 */
uint32_t *pb); /* in: seed2, out: hash2 */
这是尝试导入它的haskell代码:
{-# LANGUAGE BangPatterns, ForeignFunctionInterface #-}
import Data.Word (Word32, Word64)
import Foreign.C.Types (CSize)
import Foreign.Marshal.Utils (with)
import Foreign.Ptr (Ptr, castPtr, plusPtr)
import Foreign.Storable (Storable, peek, sizeOf)
foreign import ccall unsafe "lookup3.h hashword2" hashWord2
:: Ptr Word32 -> CSize -> Ptr Word32 -> Ptr Word32 -> IO ()
当我尝试编译它时ghc
会出现以下错误消息:
Unacceptable argument type in foreign declaration: CSize
When checking declaration:
foreign import ccall unsafe "static lookup3.h hashword2" hashWord2
:: Ptr Word32 -> CSize -> Ptr Word32 -> Ptr Word32 -> IO ()
我应该使用什么类型来整理size_t
?如果我替换CSize
并使用Word64
代替它会编译,但Word64
不可移植,对吧?
答案 0 :(得分:8)
问题是您导入CSize
作为抽象类型。 FFI允许类型的新类型包装版本,例如Word64
,但前提是它实际上可以看到包含的类型。
在您的情况下,将相应的导入行更改为
import Foreign.C.Types (CSize(..))
应该这样做。