序列化C风格的结构(使用C++)

Sta*_*ked 3 c c++ serialization

使用memcpy序列化struct对象是不是很邪恶?

在我的一个项目中,我正在执行以下操作:我记住一个struct对象,base64对其进行编码,然后将其写入文件.我在解析数据时做了反向.它似乎工作正常,但在某些情况下(例如,当使用WINDOWPLACEMENTWindows Media Player的HWND时),事实证明解码数据不匹配sizeof(WINDOWPLACEMENT).

以下是一些代码片段:

// Using WINDOWPLACEMENT from Windows API headers:
typedef struct tagWINDOWPLACEMENT {
    UINT  length;
    UINT  flags;
    UINT  showCmd;
    POINT ptMinPosition;
    POINT ptMaxPosition;
    RECT  rcNormalPosition;
#ifdef _MAC
    RECT  rcDevice;
#endif
} WINDOWPLACEMENT;


static std::string EncodeWindowPlacement(const WINDOWPLACEMENT & inWindowPlacement)
{
    std::stringstream ss;
    {
        Poco::Base64Encoder encoder(ss); // From the Poco C++ libraries
        const char * offset = reinterpret_cast<const char*>(&inWindowPlacement);
        std::vector<char> buffer(offset, offset + sizeof(inWindowPlacement));
        for (size_t idx = 0; idx != buffer.size(); ++idx)
        {
            encoder << buffer[idx];
        }
        encoder.close();
    }
    return ss.str();
}


static WINDOWPLACEMENT DecodeWindowPlacement(const std::string & inEncoded)
{
    std::string decodedString;
    {
        std::istringstream istr(inEncoded);
        Poco::Base64Decoder decoder(istr); // From the Poco C++ libraries
        decoder >> decodedString;
        assert(decoder.eof());
        if (decoder.fail())
        {
            throw std::runtime_error("Failed to parse Window placement data from the configuration file.");
        }
    }

    if (decodedString.size() != sizeof(WINDOWPLACEMENT))
    {
        // !! Occurs frequently !!
        throw std::runtime_error("Errors occured during parsing of the Window placement.");
    }

    WINDOWPLACEMENT windowPlacement;
    memcpy(&windowPlacement, &decodedString[0], decodedString.size());
    return windowPlacement;
}
Run Code Online (Sandbox Code Playgroud)

我知道使用memcpy在C++中复制类可能会导致麻烦,因为复制构造函数没有正确执行.我不确定这是否也适用于C风格的结构.或者通过内存转储序列化根本没有完成

更新:Poco的Base64Encoder/Decoder中的错误并非不可能,但不太可能.它的测试用例看起来非常彻底:Base64Test.cpp.

tob*_*ies 6

如果您需要在不具有相同字节序和字大小的计算机之间传输这些文件,或者在将来的版本中添加/删除结构中的插槽并且需要保留二进制兼容性,则会遇到问题.