2

Haskell プログラムで、C ヘッダーで定義された定数を使用する最良の方法は何ですか?

4

2 に答える 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.hscMain-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

これらをすべて 1 行に入れると、構文エラーが発生します。

于 2009-06-22T22:01:07.353 に答える
4

GHCは可能な限り離れ-fvia-cたり近づいたりしています。-fasm

副作用の 1 つは-fvia-c、コンパイル結果がモードの GHC と機能的に同一であることを保証するために、モードであっても、C ヘッダーをまったく使用せずにプログラムがコンパイルされる可能性があること-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'd 定数はよりトリッキーです。私は常にそれらをインラインでコピーするか、追加の C を使用して列挙型または const 変数に変換してきました。

于 2009-06-22T22:24:26.977 に答える