2

structバイナリを使用してC++を直接書き込むことによってシリアル化されたファイルがいくつかありますfstream。ここで、対応するC#クラスの読み取りメソッドを生成すると、おそらく構造体のパッキングが原因で、これらが実際には1対1にマップされていないことがわかります。

だから私の質問は-状況を処理するための最良の方法は何ですか?私はC++とC#の両方のソースコードを持っているので、どちらの部分も変更できます。パッキングせずにC++をシリアル化する必要がありますか(これはで行われると思い#pragma pack(1)ます)、代わりにギャップを考慮してC#コードを調整する必要がありますか?

それとも、逆シリアル化の問題は完全に異なり、パッキングとは関係ありませんか?

更新1C++enumの長さが4バイトで、bool値の長さが2バイトであることを発見しました(誰が知っていましたか?)が、追加した後でも#pragma pack(1)、最初のレコードしか正しく読み取ることができません。また、バイト数をチェックしsizeof(MyStructure)、値が一致していることを確認しました。これは、レコード間にパディングがあることを意味している必要があります。

アップデート2ダーン、コードにバグが見つかりました。コピー&ペーストエラー。PVSStudioか何かが必要です。今はすべて良いです。(そして、ええ、ブール値は1バイトの大きさです。)

4

1 に答える 1

2

アライメントが問題の原因である可能性があります。

構造体のパッキング/バイトアラインメントはコンパイラの実装に依存し、問題のハードウェアに最適化するためにビルドターゲットによっても異なります。これは、コンパイラが特定のビルドに対してたまたま生成する構造アラインメントの特定のセットに依存しないことが賢明であることを意味します。

構造を確実に共有する必要がある#pragma pack(1)場合、パフォーマンスが問題になる場合は、手動でパディングを追加して戻すのが最善です。これは、構造がタイトな内部ループで使用されている場合にのみ問題になる可能性があります。

手動調整の例:

struct Record {
    char c;
    char __padding[7];
    double d;
};

C#コードは次のようになります。

this.c = reader.ReadChar();
reader.ReadBytes(7); // or reader.BaseStream.Seek(7, SeekOrigin.Current);
this.d = reader.ReadDouble();
于 2012-03-27T07:50:56.863 に答える