私は(テンプレートHaskellを使用して)小さなツールを作成しました。これは、プリミティブ型(Int、Float、Double、Char、Bool)、マーシャラブルタイプのリスト、およびマーシャラブルタイプで構成される構造体で構成されるデータ型を対応するデータ型に自動的にマーシャリングします。 Cタイプ。
- プリミティブ型はCの対応物になります:Int-> int、Float->float。Boolはintになります。
- 「構造体」(データS = S ...)は、Haskellの「構造体」のマーシャリングされたメンバーを持つ構造体へのポインターになります。
- 配列([S])は、その型へのポインターの配列へのポインターと、そこにある要素の数を示すintで構成される構造体へのポインターになります。
したがって、この:
data Test = Test [MyStruct] Int
data MyStruct = MyStruct Int
Cでは次のようになります。
struct MyStruct {
int x;
}
struct ArrayStruct {
MyStruct** array;
int count;
}
struct Test {
ArrayStruct* arr_str;
int y;
}
ツールは次のとおりです:
https ://github.com/food2games/fieldmarshal
(C#部分もありますが、HsFieldMarshalが必要です。)これは2つのファイルで構成されており、コードにコピーするだけです。使用法:
$(makeStorable ''YourType)
サブタイプに対して自動的に保存可能なコードを実行しないことに注意してください。したがって、これがある場合:
data Type1 = Type1 Int Float
data Type2 = Type2 Int Type1
各データ型に保存可能なインスタンスを生成する必要があるよりも:
$(makeStorable ''Type1)
$(makeStorable ''Type2)
また、Storableインスタンスの生成よりも前にデータ型を宣言する必要があることに注意してください(これはTHが原因です)。したがって、これは機能しません。
$(makeStorable ''Wrong)
data Wrong = Wrong Int
これは絶対に絶対確実というわけではなく、単純なアプリには十分ですが、より複雑なコードで作業している場合は、物事がかなり簡単に台無しになる可能性があります。