2

我有一些文件已通过struct使用二进制文件直接编写 C++ 进行序列化fstream。现在,当我为相应的 C# 类生成读取方法时,我发现这些方法并不是真正的一对一映射,可能是因为结构打包。

所以我的问题是 - 处理这种情况的最佳方法是什么?我有 C++ 和 C# 源代码,所以我可以更改任何一部分。我应该尝试在不打包的情况下序列化 C++(我假设这是用 完成的#pragma pack(1),对)还是以某种方式调整我的 C# 代码以考虑这些差距?

还是反序列化的问题完全不同,与打包无关?

更新 1我发现 C++enum的长度为 4 个字节,bool值的长度为 2 个字节(谁知道?),但即使添加后#pragma pack(1)我也只能正确读取第一条记录。另外,我检查了字节数sizeof(MyStructure)和值是否匹配。这一定意味着记录之间有一些填充。

更新 2该死,在代码中发现了一个错误。复制粘贴错误。需要 PVS Studio 什么的。现在一切都好。(是的,一个布尔值是 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 回答