2011-11-11 28 views
3

いくつかのC構造体に対してHaskell FFIバインディングを記述しようとしています。例は以下の通りです:Haskell FFI for C再帰的構造体と共用体

typedef struct s0{int a; 
        union{unsigned char b; 
         struct s0*c; 
         struct{unsigned char d[1]; 
         }; };}*S; 

私の質問はc2hs用)、CHSまたはHSC(のためのhsc2hs)形式でのバインディングを作成する方法ですか?私はc2hsのチュートリアルを調べましたが、十分な情報が得られなかったか、途中でそれを理解できなかったので、上記定義のためにchsファイルを書くのに役立ちました。

私はHSFFIGツールを使用してhaskellバインディングを生成できますが、カスタムアクセスメソッドHSFFIG.FieldAccess.FieldAccessを使用してバインディングを定義しています。私は、サードパーティのライブラリではなく、コアのhaskell FFIライブラリを使用するバインディングを作成することを好みます。

したがって、上記の再帰的な構造体のバインディングをhsc形式で記述する方法、またはコアFFIライブラリのみを使用するchs形式を作成する方法に関するこの質問。

実際の定義はもっと複雑ですが、c2hsやhsc2hsツールの構造体定義の上に書く方法を理解したら、そこから行くことができます。私は知っているStorableインスタンスは、内部共用体と構造体のために定義する必要がありますが、上記のような再帰的定義のためのラッパーを書く方法を知らない。特に、内部構造体/共用体から外部構造体にアクセスするにはどうすればよいですか?私はHSFFIGの定義を検討しましたが、アクセス方法はHSFFIGで定義されたアクセス方法です。だから、私はそれをコアFFIライブラリだけを使用するchs定義にどのように翻訳するかを理解することができませんでした。

私がStackOverflowで見た質問は、より単純な定義のようです。他の場所で同様の回答がある場合は、私は指摘を感謝します。

+0

実際にデータを処理する必要はありますか? void型のデータ型を使用することができます。 – alternative

+0

はい、データを処理する必要があります。上記の構造体へのポインタは、引数の1つとして別のFFI C関数に渡され、その関数によって構造体の値が返されます。 – Sal

+0

はあなたがデータを気にするようには聞こえません。 – alternative

答えて

1

c2hsまたはhsc2hsでequivデータ構造をマジックアップすることはできません。しかし、であり、ちょっとした作業でc2hsでマーシャリングを行います。

data MyType = Next MyType | MyChar Char | MyString String | MyEnd 

その後がMyTypeためのポインタを宣言するhsc2hs' newtypeのポインタ機能を使用する(すなわち。S0)。次に、hsc2hsのアクセサを使用して明示的な関数を記述して、構造を再帰的に歩き、Haskell構造を構築します。各ステップでヌルポインタを押したかどうかテストし、そうであればMyEndを返します(またはデータエンコーディングに応じて、ユニオンの型を示すintが負であるかどうかをチェックするだけです)。そうでなければ解析を進めますあなたが持っているものがあれば、それがポインタであれば、再帰的に進みます。

hsc2hsでもほとんど同じことができます。