如何解包在QByteArray中的32位整数?

问题描述 投票:2回答:4

我正在使用串行通信,我收到了32位的整数,在一个QByteArray中的 QByteArray我试图用下面的方法从这4个字节中解压。QByteArray::toLong() 但它的转换失败,并返回错误的数字。

quint8 packed_bytes[] { 0x12, 0x34, 0x56, 0x78 };
QByteArray packed_array { QByteArray(reinterpret_cast<char*>(packed_bytes),
                                     sizeof(packed_bytes)) };
bool isConversionOK;
qint64 unpacked_value { packed_array.toLong(&isConversionOK) };
// At this point:
// unpacked_value == 0
// isConversionOK == false

预期的 unpacked_value 是0x78563412(小二烯解包)。为什么转换失败?

qt type-conversion qt5 unpack qbytearray
4个回答
4
投票

你可以使用 QDataStream 读取二进制数据。

quint8 packed_bytes[] { 0x12, 0x34, 0x56, 0x78 };
QByteArray packed_array { QByteArray(reinterpret_cast<char*>(packed_bytes), sizeof(packed_bytes)) };
QDataStream stream(packed_array);
stream.setByteOrder(QDataStream::LittleEndian);
int result;
stream >> result;
qDebug() << QString::number(result,16);

3
投票

toLong() 转换一个char *数字 string 到长。而不是字节。而你的值很可能无法构成字符串 "0x78563412 "或其十进制等值。因此结果为0。

如果你需要将字节值解释为长,你可以做类似的事情。

long value;
value == *((long*)packed_bytes.data());

或者把一个字节数组当作长数组来访问。

long * values;
values == (long*)packed_bytes.data();

values[0]; // contains first long
values[1]; // contains second long
...

我不知道我的例子是否能用得上 但它应该能清楚地说明这个原理。

看看这个例子。

char bytes[] = {255, 0};

QByteArray b(bytes, 2);

QByteArray c("255");

qDebug() << b.toShort() << c.toShort();

qDebug() << *((short*)b.data()) << *((short*)c.data());

输出是:

0 255 
255 13618

你可能需要改变字节顺序,这取决于endianess。但它能满足你的需要。


1
投票

你可以用位操作器来构建你的qint64。

#include <QtGlobal>
#include <QByteArray>
#include <QDebug>

int main()
{
    quint8 packed_bytes[] { 0x12, 0x34, 0x56, 0x78 };
    QByteArray packed_array { QByteArray(reinterpret_cast<char*>(packed_bytes),
                                         sizeof(packed_bytes)) };

    qint64 unpacked_value = 0;

    unpacked_value |=   packed_array.at(0)       |
                        packed_array.at(1) << 8  |
                        packed_array.at(2) << 16 |
                        packed_array.at(3) << 24;

    qDebug() << QString("0x%1").arg(unpacked_value, 0, 16);
}

0
投票

这里有一个 通用 转换方案 QByteArray 变成 "其他类型"(如问题中特别问到的),将其通过 QDataStream (按接受的答案做)。

免责声明。 我只是提倡在私人执行中使用这个。 我知道有很多方法可以滥用这个宏!使用这个宏,你可以很容易地产生很多转换函数,比如我提供的例子。

使用这个宏,你可以很容易地产生许多转换函数,比如我提供的例子。 如果你需要从一个流中提取各种类型,以这种方式定义一系列这样的函数可能会很有用。 显然,你可以根据你的使用情况对宏进行调整,关键在于 模式 可以基本不变,放在这样的宏中。

#define byteArrayToType( data, order, type ) \
    QDataStream stream( data ); \
    stream.setByteOrder( order ); \
    type t; \
    stream >> t; \
    return t;

例函数,简单地将宏包起来。

16位,有符号

qint16 toQInt16( const QByteArray &data,
                 const QDataStream::ByteOrder order=QDataStream::BigEndian )
{ byteArrayToType( data, order, qint16 ) }

32位,签名

qint32 toQInt32( const QByteArray &data,
                 const QDataStream::ByteOrder order=QDataStream::BigEndian )
{ byteArrayToType( data, order, qint32 ) }

64位,签名

qint64 toQInt64( const QByteArray &data,
                 const QDataStream::ByteOrder order=QDataStream::BigEndian )
{ byteArrayToType( data, order, qint64 ) }
© www.soinside.com 2019 - 2024. All rights reserved.