在 Haskell 程序中,使用 C 头文件中定义的常量的最佳方法是什么?
问问题
955 次
2 回答
6
对于这项任务,hsc2hs是您的朋友。
举个简单的例子,让我们获取INT_MAX
from的值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
将它们全部放在一行会导致语法错误。
于 2009-06-22T22:01:07.353 回答
4
GHC 正在尽可能地远离-fvia-c
和走向。-fasm
一个副作用是你的程序可以在不使用任何 C 头文件的情况下进行编译,即使在-fvia-c
模式下也是如此,以确保编译结果在功能上与-fasm
模式下的 GHC 相同。
因此,有必要在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
'd 常量是一个棘手的问题。我一直只是将它们内联复制,或者使用额外的 C 将它们转换为枚举或 const 变量。
于 2009-06-22T22:24:26.977 回答