سؤال

I've got a few files that have been serialized by directly writing C++ structs using a binary fstream. Now, when I generate the read methods for corresponding C# classes, I find out that these don't really map 1-to-1, probably because of structure packing.

So my question is - what is the best way to handle the situation? I've got both C++ and C# source code, so I can change either part. Should I attempt to serialize C++ without packing (I assume this is done with #pragma pack(1), right) or instead somehow adjust my C# code to take account of the gaps?

Or is the problem with deserializing completely different and nothing to do with packing?

Update 1 I discovered that C++ enums are 4 bytes long and bool values are 2 bytes long (who knew?), but even after adding #pragma pack(1) I am only able to correctly read the first record. Also, I've checked the number of bytes against sizeof(MyStructure) and the values match. This must mean that there is some padding between the records.

Update 2 Darn, found a bug in code. Copy-paste error. Need PVS Studio or something. All good now. (And yeah, a boolean is 1 byte big.)

هل كانت مفيدة؟

المحلول

Alignment is the likely cause of the problem.

Structure packing/byte alignment is compiler implementation dependent, and also varies with the build target to optimise for the hardware in question. This means it would be wise not to rely on a given set of structure alignments that your compiler happens to produce for a given build.

If you need to share structures reliably, it would be best to #pragma pack(1) and add the padding back in manually if performance is an issue. This is only likely to be a concern if the structures are used in a tight inner loop.

An example of manual alignment:

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

Your C# code would then look something like:

this.c = reader.ReadChar();
reader.ReadBytes(7); // or reader.BaseStream.Seek(7, SeekOrigin.Current);
this.d = reader.ReadDouble();
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top