Haskell:我如何获得#define-d常量的值?
题
在Haskell程序中,使用C头中定义的常量的最佳方法是什么?
解决方案
对于此任务, 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
将它们全部放在一行会导致语法错误。
其他提示
GHC正在尽可能地从 -fvia-c
转向 -fasm
。
一个副作用是您的程序可以在不使用任何C头的情况下进行编译,即使在 -fvia-c
模式下也是如此,以确保编译结果在功能上与GHC相同。 -fasm
模式。
因此,在 GHC编译源代码之前,必须使用 hsc2hs
, c2hs
或其他运行的预处理器。
c2hs
本身支持 enum
常量......已经有一段时间了,但我觉得这样的事情是对的。
#c
enum Foo = { Bar, Baz };
void something(enum Foo foo) {}
#endc
{#enum Foo#}
somethingBar = {#call pure something#} (cFromEnum Bar)
#define
'常量是一个棘手的问题。我总是将它们内联复制,或者使用额外的C转换为枚举或常量变量。
不隶属于 StackOverflow