2015-04-18 15 views
6

Ich versuche, ein Beispiel von Real World Haskell (Kapitel 26) zu kompilieren:FFI: Wie erklärt `size_t`

Es gibt eine C Funktion Ich möchte FFI mit nennen:

#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 */ 

hier ist der Haskell Code, der es zu importieren versucht:

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

Wenn ich versuche, es zu kompilieren ghc gibt die folgende Fehlermeldung:

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

Welchen Typ sollte ich verwenden, um eine size_t zu marshale? Wenn ich CSize ersetze und stattdessen Word64 verwende, wird es kompiliert, aber Word64 ist nicht tragbar, oder?

Antwort

8

Das Problem ist, dass Sie CSize als einen abstrakten Typ importiert haben. Das FFI ermöglicht newtype-wrap Versionen von Typen wie Word64, aber nur wenn es die enthaltenen Typen tatsächlich sehen kann.

In Ihrem Fall sollten Sie die entsprechende Importlinie

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

Änderung der Trick.

+2

Und 7.10.1 gibt eine bessere Fehlermeldung: „Inakzeptable Argumenttyp in fremder Erklärung: ‚CSize‘kann nicht in einem fremden Anruf , weil seine Daten construtor ist in ihrem Umfang Mögliche fix nicht rangieren: Importieren die Daten Konstruktor bringen Sie es in den Geltungsbereich " –

+0

Das hat es geschafft! Vielen Dank! – esato1981