2009-03-21 11 views
15

J'ai créé la bibliothèque C suivante pour lire une image:Comment utiliser les FFI de Haskell sur les structures?

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

Je ne peux pas vraiment trouver toute information à l'aide des tableaux et struct avec l'interface Fonction étrangères. Comment pourrais-je procéder pour utiliser ma bibliothèque à Haskell?

J'ai essayé d'utiliser l'exemple suivant comme base: http://therning.org/magnus/archives/315 mais le fichier hsc a été compilé jusqu'à un fichier hs qui ne contenait que le code c ci-dessus et rien de plus (et bien sûr, il ne peut pas être compilé) .

Répondre

5

Il semble que vous ayez un problème de construction; Je me rappelle avoir utilisé la page que vous avez citée comme exemple lorsque j'écrivais une interface FFI dans la bibliothèque Windows Win32 DDEML. Par exemple, l'une des structures que nous utilisons est

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

#include "ddeml.h" apporte cela dans le fichier DDEML.hsc. Nous accédons avec:

 
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 

Malheureusement, je ne peux pas vous montrer ce que cette compile au moment parce que je n'ai pas de machine Windows à portée de main, mais le code généré était comme ci-dessus, sauf #size HSZPAIR remplacé par (64) ou autre et ainsi de suite.

(Si vous voulez vraiment voir ce qui a été généré, ou besoin d'aide pour faire votre construction, e-mail moi et je vais vous aider.)

9

La prise en charge FFI de base inclut uniquement les types scalaires. Tout ce que vous finissez par faire avec l'arithmétique de l'adresse. Le section on foreign types dans la documentation FFI donne les bases, et vous pouvez trouver un exemple dans le FFI Cookbook.

En même temps, vous pouviez utiliser des outils tels que Green Card et H/Direct pour générer le code de marshalling et unmarshalling pour vous. Pour des raisons que je ne comprends pas, ces outils n'ont pas été mis à jour depuis longtemps. Autant que je sache, l'outil actuel est hsc2hs.


Edit: Comme indiqué dans le commentaire (merci de ephemient), c2hs est également populaire, et depuis c2hs est de Manuel Chakravarty, il est susceptible d'être bon.

+2

J'ai utilisé c2hs (http://www.cse.unsw.edu.au/~chak/haskell/c2hs/) dans le passé, qui est (a) encore maintenu et (b) plus facile que hsc2hs, dans mon opinion. – ephemient

+0

c2hs est un outil agréable, mais n'est pas capable de gérer des enums ou des unions – ChrisQuignon

+0

Il y a aussi 'c2hsc', pour produire des fichiers hsc principalement à partir de fichiers d'en-tête C. –

Questions connexes