Frage

Was ist in einem Haskell -Programm der beste Weg, um Konstanten zu verwenden, die in C -Headern definiert sind?

War es hilfreich?

Lösung

Für diese Aufgabe, HSC2HS ist dein Freund.

Lassen Sie uns für ein einfaches Beispiel den Wert von erhalten INT_MAX aus limits.h.

$ cat >IntMax.hsc
module Main where

#include <limits.h>

c_INT_MAX = #const INT_MAX

main = print c_INT_MAX

Mit HSC2Hs können wir #include Header und verwenden die Werte von Konstanten mit dem #const Richtlinie.

Verwenden Sie Cabal anstatt von Hand zu bauen:

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

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

Beachten Sie, dass der Name des Hauptprogramms ist, obwohl der Name des Hauptprogramms ist IntMax.hsc, das Main-Is Zeilenpunkte auf IntMax.hs. Wenn Cabal nach sucht IntMax.hs aber findet IntMax.hsc, Es füttert letztere automatisch durch HSC2HS als Teil des Builds.

$ 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

Beachten Sie, dass Sie Linien mit mehreren Konstanten aufbrechen möchten. Sagen Sie, Sie versammeln sich ein Bitfield Formatmessage. Sie werden es schreiben wollen als

flags = #const FORMAT_MESSAGE_FROM_SYSTEM
        .|.
        #const FORMAT_MESSAGE_IGNORE_INSERTS

Wenn Sie sie alle in eine Zeile setzen, führt dies zu Syntaxfehlern.

Andere Tipps

GHC bewegt sich weg von -fvia-c und in Richtung -fasm woimmer möglich.

Ein Nebeneffekt besteht -fvia-c Modus, um sicherzustellen, dass die Kompilierungsergebnisse funktional identisch mit GHC in sind -fasm Modus.

Somit ist es notwendig zu verwenden hsc2hs, c2hs, oder andere Präprozessoren laufen Vor GHC erstellt Quellen.

c2hs nativ unterstützt enum Konstanten ... Es ist eine Weile her, aber ich denke, so etwas ist richtig.

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

{#enum Foo#}

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

#define'D Konstanten sind eine Zecke schwieriger. Ich habe sie immer nur inline kopiert oder zusätzliche C verwendet, um mich in Enums- oder const -Variablen zu verwandeln.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top