当前位置: 首页 > 网络知识

Qt 大小端字节序的处理

时间:2026-01-29 09:26:57

1、Endian Order
  什么是大小端字节序(Endian Order)?以四字节十六进制整型数0x12345678为例,按照书写习惯,从左到右,高位在前,低位在后,我们称0x12为最高有效字节,0x78为最低有效字节,在存储这个数字时,需要四字节的地址空间,比如说从0x00到0x03,地址空间是从低地址0x00到高地址0x03的一段连续地址,那么,低地址存储最高有效字节的形式为大端(Big Endian),反之,高地址存储最高有效字节的形式为小端(Little Endian),也就是说,大端字节序时,地址0x00存储数字0x12,0x01存储0x34,0x02存储0x56,0x03存储0x78,反之,小端字节序时,地址0x00存储数字0x78,0x01存储0x56,0x02存储0x34,0x03存储0x12,在实际使用中,大端字节序符合我们的书写习惯。另外,对于一个字节来说,其中的八个比特位也有类似的大小端比特序,常见的最高有效位MSB(Most Significant Bit)和最低有效位LSB(Least Significant Bit)就是从这里来的。由于数据传输是逐字节的,最小单位为字节,所以我们需要关心的是大小端字节序,网络字节序为大端字节序,大小端比特序可以忽略。

2、qbswap
  对于给定的处理器来说,其大小端字节序是已知的,Qt在头文件qendian.h提供了若干对大小端进行处理的接口。首先是字节逆序函数qbswap_helper,因为在头文件中定义,所以必须指定为inline,以及模板函数qbswap,其中的转换结果dest不要求字节对齐,实现方式如下:

1 inline void qbswap_helper(const void *src, void *dest, int size) 2 6 7 template <typename T> inline void qbswap(const T src, void *dest) 8

3、考虑字节对齐

  考虑到类型安全和字节对齐安全,提供了qToUnalignedqFrUnaligned两个函数,以及六个模板特化函数qbswap,如下:

1 template <typename T> Q_ALWAYS_INLINE void qToUnaligned(const T src, void *dest) 2 11 12 template <typename T> Q_ALWAYS_INLINE T qFrUnaligned(const void *src) 13 24 25 #if (defined(Q_CC_GNU) && Q_CC_GNU >= 403) || QT_HAS_BUILTIN(__builtin_bswap32) 26 template <> inline void qbswap<quint64>(quint64 source, void *dest) 27 30 template <> inline void qbswap<quint32>(quint32 source, void *dest) 31 34 #else 35 #endif // GCC & Clang intrinsics 36 37 #if (defined(Q_CC_GNU) && Q_CC_GNU >= 408) || QT_HAS_BUILTIN(__builtin_bswap16) 38 template <> inline void qbswap<quint16>(quint16 source, void *dest) 39 42 #else 43 #endif // GCC & Clang intrinsics 44 45 // signed specializations 46 template <> inline void qbswap<qint64>(qint64 source, void *dest) 47 50 51 template <> inline void qbswap<qint32>(qint32 source, void *dest) 52 55 56 template <> inline void qbswap<qint16>(qint16 source, void *dest) 57

4、不考虑字节对齐

  如果不考虑字节对齐问题,使用另一个版本的重载函数qbswap更方便,同样有六个特化模板,如下:

1 template <typename T> T qbswap(T source); 2 3 #if (defined(Q_CC_GNU) && Q_CC_GNU >= 403) || QT_HAS_BUILTIN(__builtin_bswap32) 4 template <> inline quint64 qbswap<quint64>(quint64 source) 5 8 template <> inline quint32 qbswap<quint32>(quint32 source) 9 12 #else 13 template <> inline quint64 qbswap<quint64>(quint64 source) 14 25 26 template <> inline quint32 qbswap<quint32>(quint32 source) 27 34 #endif // GCC & Clang intrinsics 35 36 #if (defined(Q_CC_GNU) && Q_CC_GNU >= 408) || QT_HAS_BUILTIN(__builtin_bswap16) 37 template <> inline quint16 qbswap<quint16>(quint16 source) 38 41 #else 42 template <> inline quint16 qbswap<quint16>(quint16 source) 43 48 #endif // GCC & Clang intrinsics 49 50 51 // signed specializations 52 template <> inline qint64 qbswap<qint64>(qint64 source) 53 56 57 template <> inline qint32 qbswap<qint32>(qint32 source) 58 61 62 template <> inline qint16 qbswap<qint16>(qint16 source) 66 }

5、8 Bits

  对于8个二进制位的类型来说,是不需要考虑大小端的,如下:

1 template <> inline quint8 qbswap<quint8>(quint8 source) 2 5 6 template <> inline qint8 qbswap<qint8>(qint8 source) 7

6、大小端转换

  大小端转换涉及如下六个函数:

1 #if Q_BYTE_ORDER == Q_BIG_ENDIAN 2 3 template <typename T> inline T qToBigEndian(T source) 4 5 template <typename T> inline T qFrBigEndian(T source) 6 7 template <typename T> inline T qToLittleEndian(T source) 8 9 template <typename T> inline T qFrLittleEndian(T source) 10 11 template <typename T> inline void qToBigEndian(T src, void *dest) 12 13 template <typename T> inline void qToLittleEndian(T src, void *dest) 14 15 #else // Q_LITTLE_ENDIAN 16 17 template <typename T> inline T qToBigEndian(T source) 18 19 template <typename T> inline T qFrBigEndian(T source) 20 21 template <typename T> inline T qToLittleEndian(T source) 22 23 template <typename T> inline T qFrLittleEndian(T source) 24 25 template <typename T> inline void qToBigEndian(T src, void *dest) 26 27 template <typename T> inline void qToLittleEndian(T src, void *dest) 28 29 30 #endif // Q_BYTE_ORDER == Q_BIG_ENDIAN

  如果不考虑字节对齐,还有下面几个特化模板。

1 template <typename T> inline T qFrLittleEndian(const void *src) 2 5 6 template <> inline quint8 qFrLittleEndian<quint8>(const void *src) 7 8 template <> inline qint8 qFrLittleEndian<qint8>(const void *src) 9 10 11 template <class T> inline T qFrBigEndian(const void *src) 12 15 16 template <> inline quint8 qFrBigEndian<quint8>(const void *src) 17 18 template <> inline qint8 qFrBigEndian<qint8>(const void *src) 19



上一篇:Qt QToolBox QSS设置Tab高度
下一篇:Qt "QWidget: Must construct a QApplication before a QWidget"错误
Qt
  • 英特尔与 Vertiv 合作开发液冷 AI 处理器
  • 英特尔第五代 Xeon CPU 来了:详细信息和行业反应
  • 由于云计算放缓引发扩张担忧,甲骨文股价暴跌
  • Web开发状况报告详细介绍可组合架构的优点
  • 如何使用 PowerShell 的 Get-Date Cmdlet 创建时间戳
  • 美光在数据中心需求增长后给出了强有力的预测
  • 2027服务器市场价值将接近1960亿美元
  • 生成式人工智能的下一步是什么?
  • 分享在外部存储上安装Ubuntu的5种方法技巧
  • 全球数据中心发展的关键考虑因素
  • 英特尔与 Vertiv 合作开发液冷 AI 处理器

    英特尔第五代 Xeon CPU 来了:详细信息和行业反应

    由于云计算放缓引发扩张担忧,甲骨文股价暴跌

    Web开发状况报告详细介绍可组合架构的优点

    如何使用 PowerShell 的 Get-Date Cmdlet 创建时间戳

    美光在数据中心需求增长后给出了强有力的预测

    2027服务器市场价值将接近1960亿美元

    生成式人工智能的下一步是什么?

    分享在外部存储上安装Ubuntu的5种方法技巧

    全球数据中心发展的关键考虑因素