序列化和反序列化uint64_t - 在不同平台上的不同结果

时间:2014-02-04 21:51:41

标签: c++ c serialization

我在代码中使用两个辅助函数对uint64_t进行序列化和反序列化:

void CSerializer::Write_uint64(const uint64_t& ruiValue )
{

#if BYTE_ORDER == BIG_ENDIAN
    m_vBuffer.push_back(static_cast<uint8_t>(ruiValue >> 56));
    m_vBuffer.push_back(static_cast<uint8_t>(ruiValue >> 48));
    m_vBuffer.push_back(static_cast<uint8_t>(ruiValue >> 40));
    m_vBuffer.push_back(static_cast<uint8_t>(ruiValue >> 32));
    m_vBuffer.push_back(static_cast<uint8_t>(ruiValue >> 24));
    m_vBuffer.push_back(static_cast<uint8_t>(ruiValue >> 16));
    m_vBuffer.push_back(static_cast<uint8_t>(ruiValue >> 8));
    m_vBuffer.push_back(static_cast<uint8_t>(ruiValue >> 0));
#else
    m_vBuffer.push_back(static_cast<uint8_t>(ruiValue >> 0));
    m_vBuffer.push_back(static_cast<uint8_t>(ruiValue >> 8));
    m_vBuffer.push_back(static_cast<uint8_t>(ruiValue >> 16));
    m_vBuffer.push_back(static_cast<uint8_t>(ruiValue >> 24));
    m_vBuffer.push_back(static_cast<uint8_t>(ruiValue >> 32));
    m_vBuffer.push_back(static_cast<uint8_t>(ruiValue >> 40));
    m_vBuffer.push_back(static_cast<uint8_t>(ruiValue >> 48));
    m_vBuffer.push_back(static_cast<uint8_t>(ruiValue >> 56));
#endif

}



uint64_t CSerializer::Read_uint64()
{
    uint64_t uiret;

#if BYTE_ORDER == BIG_ENDIAN
    uiret = ((static_cast<uint64_t>( m_vBuffer[m_iOffset + 0]) << 56) |
             (static_cast<uint64_t>( m_vBuffer[m_iOffset + 1]) << 48) |
             (static_cast<uint64_t>( m_vBuffer[m_iOffset + 2]) << 40) |
             (static_cast<uint64_t>( m_vBuffer[m_iOffset + 3]) << 32) |
             (static_cast<uint64_t>( m_vBuffer[m_iOffset + 4]) << 24) |
             (static_cast<uint64_t>( m_vBuffer[m_iOffset + 5]) << 16) |
             (static_cast<uint64_t>( m_vBuffer[m_iOffset + 6]) << 8) |
             (static_cast<uint64_t>( m_vBuffer[m_iOffset + 7]) << 0));
#else
    uiret = ((static_cast<uint64_t>( m_vBuffer[m_iOffset + 0]) << 0) |
             (static_cast<uint64_t>( m_vBuffer[m_iOffset + 1]) << 8) |
             (static_cast<uint64_t>( m_vBuffer[m_iOffset + 2]) << 16) |
             (static_cast<uint64_t>( m_vBuffer[m_iOffset + 3]) << 24) |
             (static_cast<uint64_t>( m_vBuffer[m_iOffset + 4]) << 32) |
             (static_cast<uint64_t>( m_vBuffer[m_iOffset + 5]) << 40) |
             (static_cast<uint64_t>( m_vBuffer[m_iOffset + 6]) << 48) |
             (static_cast<uint64_t>( m_vBuffer[m_iOffset + 7]) << 56));
#endif

    m_iOffset += sizeof(uint64_t);
    return uiret;
}

然后我用一个简单的检查来测试结果:

CSerializer _Ser;
    _Ser.Write_uint64(1234567890123456789);


    uint64_t uiResults = _Ser.Read_uint64();
    printf("- %li\n", uiResults);



    FILE *fp;
    fp=fopen("dump.dat","wb");
    for(int a = 0; a < _Ser.GetBuffer().size(); a++)
    {
        fprintf(fp, "%c", _Ser.GetBuffer()[a]);
    }
    fclose(fp);

但结果在两个平台上并不相同(Mac OSX / Raspberry),结果如下:

MacBook:SerializerTest cdr$ uname -a
Darwin MacBook.local 13.0.0 Darwin Kernel Version 13.0.0: Thu Sep 19 22:22:27 PDT 2013; root:xnu-2422.1.72~6/RELEASE_X86_64 x86_64
MacBook:SerializerTest pawel$ ./SerializerTest 
- 1234567890123456789
MacBook:SerializerTest pawel$ hexdump dump.dat 
0000000 15 81 e9 7d f4 10 22 11                        
0000008
MacBook:SerializerTest cdr$ 





root@raspberrypi:/G/SerializerTest# uname -a
Linux raspberrypi 3.10.25+ #622 PREEMPT Fri Jan 3 18:41:00 GMT 2014 armv6l GNU/Linux
root@raspberrypi:/G/SerializerTest# ./SerializerTest 
- 287445236
root@raspberrypi:/G/SerializerTest# hexdump dump.dat 
0000000 8115 7de9 10f4 1122                    
0000008
root@raspberrypi:/G/SerializerTest# 

我可以看到值(十六进制)被交换,我无法弄清楚出了什么问题......

1 个答案:

答案 0 :(得分:1)

字节没有交换,只是hexdump在某些平台上默认显示2字节的整数。您应该能够使用hexdump -C获得1字节的整数。此外,在诸如raspberry pi的32位体系结构上,printf格式“%li”(long int)也用于32位整数。您需要“%lli”才能正确显示64位int。