【问题标题】:C/C++ Convert an array of 8 bytes into a 64-bit integerC/C++ 将 8 字节数组转换为 64 位整数
【发布时间】:2019-11-20 09:39:31
【问题描述】:

在我的一项任务中,我需要将 DWORD 存储到 BYTE(s) 中,然后将它们转换回来。平台仅适用于 windows。

我在这个网站上找到了以下内容:

//Convert an array of four bytes into a 32-bit integer.
DWORD getDwordFromBytes(BYTE* b)
{
    return (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
};

这适用于将 4 个字节转换为 1 个 DWORD,但是对于 DWORD64,您将如何做到这一点?

我尝试了以下方法,但由于我丢失数据而无法正确返回:

DWORD64 getDwordFromBytes64(BYTE* b)
{
    return ((DWORD64)b[0]) | ((DWORD64)b[1] << 8) | ((DWORD64)b[2] << 16) | ((DWORD64)b[3] << 24);
};

假设我有一个字节数组:

BYTE[] = {0x38,0xf0,0x07,0x40,0x01,0x00,0x00,0x00}; //000000014007F038

我需要正确地取回 000000014007F038 (DWORD64)。

如果有人能给我一个解决方案,我将非常感激。

更新:

  • 我可以接受任何解决方案,无论是 C 还是 C++。
  • “字节顺序”可以忽略。

【问题讨论】:

  • 如果你弄清楚了字节序,std::memcpy 可能会工作得很好。
  • 继续这个模式,直到你处理完这 8 个字节。
  • 感谢大家的及时回复,我添加了一个“更新”,我声明 c 或 c++ 很好,可以忽略 endian-ess。
  • 您的第一步应该是了解 32 位版本的工作原理。然后您可以轻松地将其推广到任何位宽。
  • getDwordFromBytes 有一个错误。如果b[3] &gt; 127,它会调用未定义的行为,因为它会溢出整数提升表达式(b[3] &lt;&lt; 24)

标签: c++ c windows


【解决方案1】:

如果您关心字节顺序并且不想使用任何指针或联合双关语

#define to64b(arr) (((uint64_t)(((uint8_t *)(arr))[7]) <<  0)+\ 
                    ((uint64_t)(((uint8_t *)(arr))[6]) <<  8)+\
                    ((uint64_t)(((uint8_t *)(arr))[5]) << 16)+\
                    ((uint64_t)(((uint8_t *)(arr))[4]) << 24)+\
                    ((uint64_t)(((uint8_t *)(arr))[3]) << 32)+\
                    ((uint64_t)(((uint8_t *)(arr))[2]) << 40)+\
                    ((uint64_t)(((uint8_t *)(arr))[1]) << 48)+\
                    ((uint64_t)(((uint8_t *)(arr))[0]) << 56))

#define to64l(arr) (((uint64_t)(((uint8_t *)(arr))[0]) <<  0)+\ 
                    ((uint64_t)(((uint8_t *)(arr))[1]) <<  8)+\
                    ((uint64_t)(((uint8_t *)(arr))[2]) << 16)+\
                    ((uint64_t)(((uint8_t *)(arr))[3]) << 24)+\
                    ((uint64_t)(((uint8_t *)(arr))[4]) << 32)+\
                    ((uint64_t)(((uint8_t *)(arr))[5]) << 40)+\
                    ((uint64_t)(((uint8_t *)(arr))[6]) << 48)+\
                    ((uint64_t)(((uint8_t *)(arr))[7]) << 56))

uint64_t toUnsigned64(const void *arr, int bigend)
{
    return bigend ? to64b(arr) : to64l(arr);   
}

【讨论】:

  • 对,我的错,所有这些括号使它无法阅读。我会考虑通过在函数中添加一个临时指针来修复:const uint8_t* u8 = arr;,然后瞧,宏中的每一行都可以简化为((uint64_t)arr[7] &lt;&lt; 56)。或者,如果对宏观安全持迂腐态度,((uint64_t)(arr)[7] &lt;&lt; 56)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-20
  • 1970-01-01
  • 2011-04-21
  • 1970-01-01
  • 2015-06-09
  • 2017-06-27
  • 2016-01-03
相关资源
最近更新 更多