【问题标题】:How to convert a QByteArray in little endian format to a unsigned long如何将小端格式的 QByteArray 转换为无符号长整数
【发布时间】:2020-04-01 00:56:45
【问题描述】:

我有一个 QByteArray,它有 4 个小端格式的值

QByteArray ba;
ba.append(0xbb);
ba.append(0x1c);
ba.append(0x51);
ba.append(0x1e);

要将 ba 转换为大端,我执行以下操作:

baBigEndian[0] = ba[3];
baBigEndian[1] = ba[2];
baBigEndian[2] = ba[1];
baBigEndian[3] = ba[0];

要将大端数组转换为无符号长整数,我尝试了以下方法:

baBigEndian.toULong(&ok,10);

小端字节数组已正确转换为大端,但 .toULong 返回 0 而不是 508632251。

如何将 baBigEndian 数组转换为无符号长整数?或者有没有办法直接从小端数组转换为无符号长?

提前致谢!

【问题讨论】:

  • 您希望这段代码在所有 CPU(包括大端和小端)上运行吗?
  • 我通过串行连接获取字节数组的字节,所以我不确定它是否重要(可能所有 CPU 只是为了安全)
  • 这很重要,因为例如PowerPC CPU 将希望以不同的顺序查看这些字节,例如英特尔 CPU。也就是说,ntohl() 函数(如下面的回答所示)将在所有情况下正确处理该问题。

标签: c++ qt endianness qbytearray ulong


【解决方案1】:

试试memcpy

quint32 value = 0; //or qint32
memcpy(&value, baBigEndian.data(), sizeof(quint32));//or baBigEndian instead baBigEndian.data() if you use plain array instead QByteArray

另外,可以使用reinterpret_cast 完成,但我不建议您使用reinterpret_cast,因为我在arm 处理器上遇到了一些问题(而在x86 上它工作正常)。

【讨论】:

  • Reinterpret_cast 不适用于 little-endian 架构。如今,大多数架构都是小端的。
  • 使用 memcpy 像你说明的那样返回 3139195166 而不是 508632251
  • 508632251 是 0x1e511cbb(变量 ba),3139195166 是 0xBB1C511E(变量 baBigEndian)。所以在我的示例中,将baBigEndian 替换为ba。我不知道你到底想转换什么变量
【解决方案2】:

toULong() 不起作用,因为它希望 QByteArray 包含 ASCII 格式的数字的字符串表示形式(例如 "0xbb1c511e",它是 10 个 ASCII 字节),而您的 QByteArray 包含文字二进制字节(例如0xbb1c511e,即4个二进制字节)。

假设您的 QByteArray 包含大端格式的四个字节(就像在示例代码中的第 2 步之后所做的那样),那么这将起作用:

unsigned long val = ntohl(*((const unsigned long *)ba.data()));

但请注意,sizeof(unsigned long) 不能保证在所有平台上都是 4 字节,因此最好使用保证始终为 4 字节宽的固定宽度类型,例如

quint32 val = ntohl(*((const quint32 *)ba.data()));

【讨论】:

  • 我应该#include 什么才能使用ntohl()
猜你喜欢
  • 2020-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-19
  • 2017-03-15
  • 1970-01-01
  • 1970-01-01
  • 2015-04-05
相关资源
最近更新 更多