我在mac和linux上编译并运行成功的软件框架。我现在正试图将它移植到Windows(使用mingw)。到目前为止,我有在Windows下编译和运行的软件,但它不可避免地有错误。特别是,我有一个问题,就是将在macos(或linux)中序列化的数据读入程序的windows版本(segfaults)。
序列化过程将原始变量(long,int,double等)的值序列化到磁盘。
这是我正在使用的代码:
#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));
}
因此,为了保存一堆变量的状态,我依次为每个变量调用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中,这种序列化数据的读取失败了。我猜测窗口序列化数据有点不同。我想知道是否有一种方法可以修改上面的代码,以便可以在任何其他平台上读取任何平台上保存的数据...任何想法?
干杯,
本。
答案 0 :(得分:2)
这只是一个疯狂的猜测,我无法帮助你。我的想法是字节顺序不同:big endian vs little endian。因此,当加载到顺序颠倒的机器上时,任何大于一个字节的东西都会被弄乱。
例如,我在msdn中找到了这种代码的和平:
int isLittleEndian() {
long int testInt = 0x12345678;
char *pMem;
pMem = (char *) testInt;
if (pMem[0] == 0x78)
return(1);
else
return(0);
}
我猜你在linux vs windows上会有不同的结果。最好的情况是,如果有一个标志选项供您的编译器使用一种格式或另一种格式。只需在所有机器上将其设置为相同即可。
希望这有帮助, 亚历
答案 1 :(得分:2)
但是,当你这样做时,你真的不能使用类型规范。 <{1}},int
,float
尺寸都可以跨平台进行更改。
对于整数类型,请使用cstdint标头中的严格大小类型。 size_t
,uint32_t
等.Windows没有可用的标头iirc,但您可以改用boost / cstdint.hpp。
浮点应该可以工作,因为大多数编译器遵循相同的IEEE规范。
C - Serialization of the floating point numbers (floats, doubles)
二进制序列化确实需要彻底的单元测试。我强烈建议投入时间。
答案 2 :(得分:1)
再猜测一下: 你忘了在二进制阅读模式和Windows文件流中打开文件 将序列13,10转换为10.
答案 3 :(得分:0)