2009-03-21 4 views
15

Ich habe die folgende C-Bibliothek zum Lesen eines Bildes erstellt:Wie verwende ich Haskells FFI auf Strukturen?

typedef struct { 
    unsigned int height; 
    unsigned int width; 

    unsigned char* red; //length=height*width 
    unsigned char* green; 
    unsigned char* blue; 
} Contents; 

Contents readJPEGFile(const char* inFilename); 

ich irgendwelche Informationen nicht wirklich finden können Arrays und Strukturen mit dem Foreign Function Interface. Wie würde ich fortfahren, meine Bibliothek in Haskell verwenden zu können?

Ich habe versucht, das folgende Beispiel als Basis zu verwenden: http://therning.org/magnus/archives/315 aber dann wurde die HSC-Datei in eine HS-Datei kompiliert, die nur den obigen C-Code und nichts mehr enthielt (und natürlich kann nicht kompiliert werden) .

Antwort

5

Es klingt, als ob Sie ein Build-Problem haben; Ich erinnere mich, dass ich die Seite, auf die Sie verweisen, als Beispiel verwendet habe, als ich eine FFI-Schnittstelle in die Windows-Win32-DDEML-Bibliothek geschrieben habe. Zum Beispiel, eine der Strukturen, die wir verwenden, ist

typedef struct tagHSZPAIR { 
    HSZ  hszSvc; 
    HSZ  hszTopic; 
} HSZPAIR, *PHSZPAIR; 

#include "ddeml.h" diese in die DDEML.hsc Datei bringt. Wir greifen sie mit:

 
data HSZPair = HSZPair HSZ HSZ 
instance Storable HSZPair where 
    sizeOf _      = (#size HSZPAIR) 
    alignment     = sizeOf 
    peek ptr      = do svc <- (#peek HSZPAIR, hszSvc) ptr 
             topic <- (#peek HSZPAIR, hszTopic) ptr 
             return $ HSZPair svc topic 
    poke ptr (HSZPair svc topic) = do (#poke HSZPAIR, hszSvc) ptr svc 
             (#poke HSZPAIR, hszTopic) ptr topic 

Leider kann ich Ihnen nicht zeigen, was dies im Moment kompiliert, weil ich praktisch keine Windows haben Kasten, aber der erzeugte Code war nur wie oben, nur mit #size HSZPAIR ersetzt mit (64) oder was auch immer und so weiter.

(Wenn Sie wirklich, was Sie wollen, um zu sehen erzeugt wurde, oder die Hilfe benötigen, Ihren Build zu tun, mir eine E-Mail und ich werde Ihnen helfen.)

9

Die grundlegende FFI-Unterstützung umfasst nur skalare Typen. Alles andere, was Sie mit Adressarithmetik tun. Die section on foreign types in der FFI-Dokumentation enthält die Grundlagen und Sie finden ein Beispiel in der FFI Cookbook.

Auf einmal könnten Sie Tools wie Green Card und H/Direct verwenden, um Marshalling- und Unmarshalling-Code für Sie zu generieren. Aus Gründen, die ich nicht verstehe, wurden diese Tools seit langer Zeit nicht mehr aktualisiert. Soweit ich feststellen kann, ist das aktuelle Werkzeug der Wahl hsc2hs.


Edit: Wie in Kommentar (Dank ephemient) erwähnt, c2hs ist auch sehr beliebt, und da c2hs von Manuel Chakravarty ist, ist es wahrscheinlich gut sein.

+2

Ich habe in der Vergangenheit c2hs (http://www.cse.unsw.edu.au/~chak/haskell/c2hs/) verwendet, die (a) noch gepflegt ist und (b) einfacher als hsc2hs, in meinem Meinung. – ephemient

+0

c2hs ist ein nettes Tool, aber es ist nicht in der Lage Enums oder Unionen zu verwalten – ChrisQuignon

+0

Es gibt auch 'c2hsc', um hsc-Dateien größtenteils automatisch aus C-Header-Dateien zu erzeugen. –