2012-06-21 4 views
18

ハスケルコードをCライブラリに埋め込むことができるので、ライブラリのユーザはハスケルが使用されていることを知る必要はありませんか?特に、ユーザーがHaskellを組み込んだ複数のライブラリを競合することなく使用できるようにするには?HaskellをCライブラリに不透明に埋め込むことは可能ですか?

私が理解する限り、hs_initとhs_exitの呼び出しの間に埋め込みますが、これらはグローバル状態の偽装を伴い、他の呼び出しと競合するでしょうか?いいえ?

答えて

14

はい、というFFIでHaskellコードをCから(またはその逆に)呼び出すのはpossibleです。 ()

呼び出しがhs_initするGHCのランタイムシステムを初期化しますhaskell.org docsが言うように残念ながら、あなたは初期化し、Haskellの環境を完成させるために呼び出しを避けることができません。 hs_init()を呼び出す前に、 がHaskell関数を呼び出そうとしないでください。悪いことは間違いなく起こります。

しかし、thisも興味深いです:

ありhs_initの複数の呼び出し()、ことができますが、それぞれが1つだけにマッチした でなければなりません(hs_exitするために呼び出す)

そしてfurthermore

FFIの仕様は、実装が必要hs_exit()でシャットダウンした後に 自身を再初期化することをサポートしていますが、GHCでは現在 がサポートされていません。

基本的に私のアイデアは、あなたがhs_initとすることができますhs_exitに囲まれたテンプレートメソッドを使用しての例では、youselfにあなたのためにhs_iniths_exitに通話を管理ラッパーC++クラスを記述するために、この仕様を利用することができるということです任意のhaskell呼び出しを使用してオーバーライドします。 しかし、他のライブラリとのやりとりは、haskellコードを呼び出すことに注意してください:hs_iniths_exitへの呼び出しのネストされたレイヤーはOKです(ラッパーの間で呼び出すライブラリを使用することは安全です)つまり、それらのライブラリが環境を終了させずに初期化するだけであれば、その作業を終了するのはあなた次第です。

別の(おそらくより良い)アイデアは、継承とオーバーライドを利用せずに、デストラクタでコンストラクタとhs_exiths_initを呼び出す単純なクラスHaskellEnvを持っているかもしれません。自動変数として宣言すると、とhs_exitへの呼び出しが常に一致し、最新のhs_exitの呼び出しは、スコープを離れるときに最新のHaskellEnvオブジェクトが破棄されるとすぐに行われます。 ヒープ上にオブジェクトを作成しないようにするには、this questionを参照してください(この場合は危険です)。

+0

私はすでにそれが可能であることを知っています。 _safely_することが可能かどうかを知りたい。 –

+0

あなたは 'hs_init'と' hs_exit'を呼び出すことに注意しなければなりません。それらの呼び出しを安全な方法でラップするためにラッパーC++クラスを自分自身でコーディングしようとするかもしれませんが、それはあなた次第です。私の頭に浮かぶ最初の方法は、hs_initとhs_exitで囲まれたテンプレートメソッドを使用することです。これはあなたが望む任意のhaskell呼び出しを使ってオーバーライドすることができます。 –

+0

それは完全に許容され、いくつかの大きなシステムで使用されます。 –