Destroy an array of bytes in the structure

I get a network transmission that is an array of characters / bytes. It contains a header and some data. I would like to match the title with the structure. Here is an example:

#pragma pack(1)

struct Header
{
    unsigned short bodyLength;
    int msgID;
    unsigned short someOtherValue;
    unsigned short protocolVersion;
};

int main()
{
    boost::array<char, 128> msgBuffer;
    Header header;

    for(int x = 0; x < sizeof(Header); x++)
        msgBuffer[x] = 0x01; // assign some values

    memcpy(&header, msgBuffer.data(), sizeof(Header));

    system("PAUSE");    

    return 0;
}

Will this always work if the structure never contains variable length fields? Is there an independent / idiomatic way of the platform?

Note:

I have seen quite a few libraries on the Internet that allow you to serialize / deserialize, but I get the impression that they can only deserialize something if it was previously serialized with the same library. Well, I do not control the transmission format. I am definitely going to get a byte / char array where all the values ​​just follow each other.

+5
6

, . .

x86 , .

. , , YAMI.

+5

, , , , ( ), , . :

GCC, .

(ints ..). .

+5

#pragma pack(1) , , (10 , ) printf("%d", sizeof(Header));, , .

, Endianness, .

+2

. , . endiannes , . . - , .

. , . , .

, , , "s s s s". (s = short, = int) , , endiannes wila. .

SwitchEndianToBig (& header, "s s s s", 4);//4 =

+1

, , AFAIK, , - , , :

#include <array>
#include <algorithm>

//#pragma pack(1) // not needed

struct Header
{
    unsigned short bodyLength;
    int msgID;
    unsigned short someOtherValue;
    unsigned short protocolVersion;
    float testFloat;

    Header() : bodyLength(42), msgID(34), someOtherValue(66), protocolVersion(69), testFloat( 3.14f ) {}
};

int main()
{
    std::tr1::array<char, 128> msgBuffer;
    Header header;

    const char* rawData = reinterpret_cast< const char* >( &header );

    std::copy( rawData, rawData + sizeof(Header), msgBuffer.data()); // assuming msgBuffer is always big enough

    system("PAUSE");    

    return 0;
}

, (typedef) , , .

+1

, , . .

, :

const int kHeaderSizeInBytes = 6;

struct Header
{
    unsigned short bodyLength;
    unsigned short msgID;
    unsigned short protocolVersion; 

    unsigned short convertUnsignedShort(char inputArray[sizeof(unsigned short)])
        {return (((unsigned char) (inputArray[0])) << 8) + (unsigned char)(inputArray[1]);}

    void operator<<(char inputArray[kHeaderSizeInBytes])
    {
        bodyLength = convertUnsignedShort(inputArray);
        msgID = convertUnsignedShort(inputArray + sizeof(bodyLength));
        protocolVersion = convertUnsignedShort(inputArray + sizeof(bodyLength) + sizeof(msgID));
    }
};

int main()
{
    boost::array<char, 128> msgBuffer;
    Header header;

    for(int x = 0; x < kHeaderSizeInBytes; x++)
        msgBuffer[x] = x;

    header << msgBuffer.data();

    system("PAUSE");    

    return 0;
}

He gets rid of pragma, but this is not such a common goal as we would like. Each time you add a field to the header, you must change the <function. Can you somehow iterate over the fields of the structure, get the type of the field and call the corresponding function?

0
source

All Articles