2009-06-22 6 views

ответ

6

Для этой задачи hsc2hs является вашим другом.

Для простого примера давайте получим значение INT_MAX от limits.h.

$ cat >IntMax.hsc 
module Main where 

#include <limits.h> 

c_INT_MAX = #const INT_MAX 

main = print c_INT_MAX 

С hsc2hs, мы можем #include заголовки и использовать значения констант с #const директивы.

Вместо здания вручную, используйте 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 

Обратите внимание, что даже если имя главной программы IntMax.hsc, на Main-Is линия указует на IntMax.hs. Когда Cabal ищет IntMax.hs, но находит IntMax.hsc, он автоматически передает последний через hsc2hs как часть сборки.

$ 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 

Обратите внимание, что вы захотите разбить линии с несколькими константами. Скажите, что вы собираете бит, чтобы перейти к FormatMessage. Вы хотите написать это как

flags = #const FORMAT_MESSAGE_FROM_SYSTEM 
     .|. 
     #const FORMAT_MESSAGE_IGNORE_INSERTS 

Ввод их всех в одну строку приведет к ошибкам синтаксиса.

4

GHC отходит от -fvia-c и в направлении -fasm, где это возможно.

Один из побочных эффектов заключается в том, что ваша программа может быть скомпилирована без использования каких-либо C-заголовков вообще, даже в режиме -fvia-c, чтобы гарантировать, что результаты компиляции функционально идентичны с GHC в режиме -fasm.

Таким образом, необходимо использовать hsc2hs, c2hs или другие препроцессоры запустить до того GHC компилирует источники.

c2hs изначально поддерживает enum константы ... это было какое-то время, но я думаю, что что-то вроде этого правильно.

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

{#enum Foo#} 

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

#define «D константы клещ сложнее. Я всегда просто скопировал их inline или использовал дополнительный C для преобразования в переменные enum или const.