FFI:如何声明`size_t`

时间:2015-04-18 12:50:06

标签: haskell ffi

我正在尝试从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不可移植,对吧?

1 个答案:

答案 0 :(得分:8)

问题是您导入CSize作为抽象类型。 FFI允许类型的新类型包装版本,例如Word64,但前提是它实际上可以看到包含的类型。

在您的情况下,将相应的导入行更改为

import Foreign.C.Types (CSize(..))

应该这样做。