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

时间:2011-11-16 15:48:58

标签: c++ windows linux g++ mingw

我在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中,这种序列化数据的读取失败了。我猜测窗口序列化数据有点不同。我想知道是否有一种方法可以修改上面的代码,以便可以在任何其他平台上读取任何平台上保存的数据...任何想法?

干杯,

本。

4 个答案:

答案 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}},intfloat尺寸都可以跨平台进行更改。

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

浮点应该可以工作,因为大多数编译器遵循相同的IEEE规范。

C - Serialization of the floating point numbers (floats, doubles)

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

答案 2 :(得分:1)

再猜测一下: 你忘了在二进制阅读模式和Windows文件流中打开文件 将序列13,10转换为10.

答案 3 :(得分:0)

您是否考虑使用序列化库或格式,例如:

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

(对于标量的序列化,htonl和伴随例程应该有帮助)