Serialization of C-style structures (using C ++)

Is it wrong to serialize structure objects using memcpy?

In one of my projects, I do the following: I have a memcpy struct object, base64 encodes it and writes it to a file. When analyzing data, I do the opposite. It seems to work fine, but in some situations (for example, when using WINDOWPLACEMENTWindows Media Player for HWND), it turns out that the decoded data does not match sizeof(WINDOWPLACEMENT).

Here are some code snippets:

// 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;
}

I am aware that copying classes in C ++ using memcpy can cause problems because copy constructors are not executed properly. I'm not sure if this applies to C-style structures either. Or is serialization via memory reset simply not done?

: Poco Base64Encoder/Decoder , . : Base64Test.cpp.

+3
5

, , , / .

+6

, operator>>() Poco::Base64Decoder. istream operator>>(), decoder >> decodedString; decodedString . , - , decoder >> decodedString; .

+3

memcpy / , (POD), case, ++, ( struct class ++).

, , - , , memcpy, , , .

, , boost.serialization, , Google ProtoBuffers .

, ++:

+3

, , , .

, , ( , ), , ( , , , ..).

. Google, - , , .

+2

, , , , , , .. , , . , . , , , , , Google .. Whitespace - , WS base64, (PoCo ). , . .

+2
source

Source: https://habr.com/ru/post/1769650/


All Articles