FFI: how to declare `size_t`

I am trying to compile an example from Real World Haskell (chapter 26):

There is a C function that I want to call using 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 */ 

Here is the haskell code that is trying to import it:

 {-# 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 () 

When trying to compile it ghc , the following error message appears:

 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 () 

What type should I use to marshal size_t ? If I replaced CSize and use Word64 , it Word64 instead, but Word64 does not migrate, right?

+6
source share
1 answer

The problem is that you imported CSize as an abstract type. FFI allows new types of types, such as Word64 , but only if it really can see hidden types.

In your case, changing the corresponding import line to

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

gotta do the trick.

+8
source

Source: https://habr.com/ru/post/985415/


All Articles