将数据序列化代码从C ++ linux / mac移植到C ++窗口

我有一个软件框架在mac和linux上编译和运行成功。 我现在试图将其移植到Windows(使用mingw)。 到目前为止,我有软件编译和运行在Windows下,但它不可避免的越野车。 特别是,我有一个阅读macos(或linux)序列化到程序的windows版本(segfaults)的数据的问题。

序列化过程序列化原始variables(长整数,整数,双精度等)的值到磁盘。

这是我正在使用的代码:

#include <iostream> #include <fstream> template <class T> void serializeVariable(T var, std::ofstream &outFile) { outFile.write (reinterpret_cast < char *>(&var),sizeof (var)); } template <class T> void readSerializedVariable(T &var, std::ifstream &inFile) { inFile.read (reinterpret_cast < char *>(&var),sizeof (var)); } 

所以为了保存一堆variables的状态,我依次调用每个variables的serializeVariable。 然后再读取数据,调用readSerializedVariable按照保存顺序进行调用。 例如保存:

 ::serializeVariable<float>(spreadx,outFile); ::serializeVariable<int>(objectDensity,outFile); ::serializeVariable<int>(popSize,outFile); 

并阅读:

 ::readSerializedVariable<float>(spreadx,inFile); ::readSerializedVariable<int>(objectDensity,inFile); ::readSerializedVariable<int>(popSize,inFile); 

但在Windows中,这个序列化数据的读取失败。 我猜测,Windows序列化数据有点不同。 我想知道是否有一种方法可以修改上面的代码,以便保存在任何平台上的数据可以在任何其他平台上读取…任何想法?

干杯,

本。

像这样的二进制序列化应该可以在这些平台上正常工作。 你必须尊重排序,但这是微不足道的。 我不认为这三个平台在这方面有什么冲突。

尽管如此,你真的不能像宽松的类型规范那样使用。 intfloatsize_t大小都可以跨平台变化。

对于整数类型,请使用cstdint标头中的严格大小的类型。 uint32_tint32_t等。Windows没有可用的iirc头文件,但是可以使用boost / cstdint.hpp。

大多数编译器遵循相同的IEEE规范,所以浮点应该起作用。

C – 浮点数的序列化(浮点数,双精度)

二进制序列化确实需要彻底的单元测试。 我强烈建议投入时间。

这只是一个疯狂的猜测,我不能帮助你更多。 我的想法是,字节顺序是不同的:大端与小端。 因此,当装载在具有相反顺序的机器上时,大于一个字节的任何东西都会被搞乱。

例如,我发现在MSDN代码的和平:

 int isLittleEndian() { long int testInt = 0x12345678; char *pMem; pMem = (char *) testInt; if (pMem[0] == 0x78) return(1); else return(0); } 

我想你会有不同的结果在Linux与Windows。 最好的情况是,如果你的编译器有一个标志选项使用一种格式或其他格式。 只需将其设置为在所有机器上相同。

希望这有助于,亚历克斯

还有一个猜测:你忘记在二进制阅读模式下打开文件,并在Windows文件流转换序列13,10到10。

你有没有考虑使用序列化库或格式,如:

  • XDR (由libc支持)或ASN1
  • s11n (一个C ++序列化库)
  • Json ,这是一个非常简单的文本格式,包含许多库,例如JsonCpp , Jansson ,Jaula,….)
  • YAML是一个功能更强大的文本格式,有许多库
  • 甚至XML ,这通常用于序列化的目的…

(对于标量序列化, htonl和companion例程应该有所帮助)