hsc2hs と c2hs の違いは何ですか?
hsc2hs がプリプロセッサであることは知っていますが、正確には何をするのでしょうか?
また、c2hs は C コードから Haskell モジュールを作成できますが、これには hsc2hs が必要ですか?
どちらも同じ機能を持っています: FFI バインディングの記述を容易にします。c2hs を使用することを選択した場合、hsc2hs について知る必要はありません。それらは独立しています。C2hs はより強力ですが、より複雑でもあります。Edward Z. Yang は、 c2hs チュートリアルでこの点を図で示しています。
いつ c2hs を使用する必要がありますか? 多くの Haskell プリプロセッサがあります。どちらを使用する必要がありますか? 上記の階層を特徴付ける簡単な (そしてやや不正確な) 方法は、下に行くほど、書く必要のある定型文が少なくなり、読む必要のあるドキュメントが増えるということです。したがって、小さな FFI プロジェクトには hsc2hs を使用し、大きなプロジェクトには c2hs を使用するべきだというアドバイスを聞いたことがあります。
c2hs がサポートし、hsc2hs がサポートしないもの:
- Cヘッダーファイルの内容に基づく外部インポートの自動生成
- 関数呼び出しとの間の半自動マーシャリング、および
- ポインター型と階層の Haskell 型への変換。
ミハイルの答えは良いですが、別の側面があります。hsc2hs が提供して c2hs が提供しないものもあり、両方を組み合わせて使用する必要がある場合があります。
特に、hsc2hs は、Haskell コードを生成するために実行される C 実行可能ファイルを生成することによって動作しますが、c2hs はヘッダー ファイルを直接解析します。したがって、hsc2hs を使用すると s などにアクセスできます。そのため、c2hs は#define
バインディングとバインディングへのラッパーの生成、および複雑な C 構造への「深い」ピークとポークの生成には優れていることがわかりましたが、定数や列挙型へのアクセスには適していません。 Storable インスタンスのボイラープレートを穏やかに自動化するだけです。特に定義済みの定数の場合、bindings-dsl パッケージ [1] と組み合わせて、hsc2hs も必要であることがわかりました。ある例では、大量の定数用に 1 つの hsc ファイルと、これらの定数を使用する関数をラップするための 1 つの chs ファイルがあります。