我有一些文件是通过使用二进制 fstream
直接编写 C++ struct
序列化的。现在,当我为相应的 C# 类生成读取方法时,我发现它们并不是真正的 1 对 1 映射,可能是因为结构打包。
所以我的问题是 - 处理这种情况的最佳方法是什么?我有 C++ 和 C# 源代码,所以我可以更改任何一部分。我应该尝试在不打包的情况下序列化 C++(我假设这是通过 #pragma pack(1)
完成的,对)还是以某种方式调整我的 C# 代码以考虑差距?
或者反序列化的问题完全不同,与打包无关?
更新 1 我发现 C++ enum
的长度为 4 个字节,而 bool
值的长度为 2 个字节(谁知道?),但是即使在添加 #pragma pack(1)
之后,我也只能正确读取第一条记录。此外,我还根据 sizeof(MyStructure)
检查了字节数并且值匹配。这一定意味着记录之间有一些填充。
更新 2 该死,在代码中发现了一个错误。复制粘贴错误。需要 PVS Studio 什么的。现在一切都好。 (是的, bool 值有 1 个字节大。)
最佳答案
对齐可能是问题的原因。
结构打包/字节对齐依赖于编译器实现,并且还随构建目标而变化以针对相关硬件进行优化。这意味着明智的做法是不要依赖编译器为给定构建生成的给定结构对齐集。
如果您需要可靠地共享结构,最好是 #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();
关于c# - 使用 BinaryReader 在 C# 中读取序列化的 C++ 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9885025/