在不同平台上序列化和应对UINT64_T-不同的结果

Serializing and Deserializing uint64_t - different results on different platforms

本文关键字:UINT64 结果 平台 序列化      更新时间:2023-10-16

i序列化并在我的代码中使用两个助手功能序列化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("- %lin", 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# 

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

字节没有互换,默认情况下hexdump在某些平台上显示2个字节INT。您应该能够使用hexdump -C获得1字节INT。同样,在32位架构(例如Raspberry Pi)上,Printf格式"%li"(长INT)也适用于32位INT。您需要"%lli"才能正确显示64位int。