2009-06-22 9 views

Répondre

6

Pour cette tâche, hsc2hs est votre ami. Pour un exemple simple, prenons la valeur INT_MAX de limits.h.

$ cat >IntMax.hsc 
module Main where 

#include <limits.h> 

c_INT_MAX = #const INT_MAX 

main = print c_INT_MAX 

Avec hsc2hs, nous pouvons #include les en-têtes et d'utiliser les valeurs des constantes de la directive #const.

au lieu de construire à la main, utilisez Cabal:

$ cat >intmax.cabal 
Name:   intmax 
Version:  0.0 
Cabal-Version: >=1.2 
Build-Type: Simple 

Executable intmax 
    Main-Is: IntMax.hs 
    Build-Depends: base 

Notez que même si le nom du programme principal est IntMax.hsc, les points de ligne Main-Is à IntMax.hs. Lorsque Cabal cherche IntMax.hs mais trouve IntMax.hsc, il alimente automatiquement ce dernier via hsc2hs dans le cadre de la construction.

$ cabal configure 
Resolving dependencies... 
Configuring intmax-0.0... 

$ cabal build 
Prerocessing executables for intmax-0.0... 
Building intmax-0.0... 
[1 of 1] Compiling Main    (dist\build\intmax\intmax-tmp\IntMax.hs, dist\build\intmax\intmax-tmp\Main.o) 
Linking dist\build\intmax\intmax.exe ... 

$ ./dist/build/intmax/intmax 
2147483647 

Notez que vous aurez envie de briser les lignes avec plusieurs constantes. Supposons que vous assemblez un champ de bits pour passer à FormatMessage. Vous aurez besoin de l'écrire comme

flags = #const FORMAT_MESSAGE_FROM_SYSTEM 
     .|. 
     #const FORMAT_MESSAGE_IGNORE_INSERTS 

Si vous les mettez tous sur une ligne, cela entraînera des erreurs de syntaxe.

4

GHC s'éloigne de -fvia-c et vers -fasm autant que possible. Un effet secondaire est que votre programme peut être compilé sans utiliser d'en-têtes C, même en mode -fvia-c, afin de garantir que les résultats de compilation sont fonctionnellement identiques à GHC en mode -fasm.

Il est donc nécessaire d'utiliser hsc2hs, c2hs, ou d'autres préprocesseurs exécuter avant GHC compile les sources.

c2hs supporte nativement enum constantes ... ça fait longtemps, mais je pense que quelque chose comme ça est juste.

#c 
enum Foo = { Bar, Baz }; 
void something(enum Foo foo) {} 
#endc 

{#enum Foo#} 

somethingBar = {#call pure something#} (cFromEnum Bar) 

#define « constantes d sont une tique plus délicate. Je les ai toujours simplement copiés en ligne, ou utilisé des C supplémentaires pour les transformer en enums ou const variables.

Questions connexes