Haskell:我如何获得#define-d常量的值?

Gre*_*con 2 haskell ffi cabal hsc2hs

在Haskell程序中,使用C头中定义的常量的最佳方法是什么?

Gre*_*con 6

对于这个任务,hsc2hs是你的朋友.

举个简单的例子,让我们得到INT_MAXfrom 的值limits.h.

$ cat >IntMax.hsc
module Main where

#include <limits.h>

c_INT_MAX = #const INT_MAX

main = print c_INT_MAX
Run Code Online (Sandbox Code Playgroud)

使用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
Run Code Online (Sandbox Code Playgroud)

请注意,即使主程序的名称是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
Run Code Online (Sandbox Code Playgroud)

请注意,您需要拆分包含多个常量的行.假设您正在组装一个位域以传递给FormatMessage.你会想把它写成

flags = #const FORMAT_MESSAGE_FROM_SYSTEM
        .|.
        #const FORMAT_MESSAGE_IGNORE_INSERTS
Run Code Online (Sandbox Code Playgroud)

将它们全部放在一行将导致语法错误.