How to unpack 32bit integer packed in a QByteArray?

梦想的初衷 提交于 2019-12-10 22:14:28

问题


I'm working with serial communication, and I receive 32bit integers in a QByteArray, packed in 4 separate bytes (little-endian). I attempt to unpack the value from the 4 bytes using QByteArray::toLong() but it fails the conversion and returns the wrong number:

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

The expected unpacked_value is 0x78563412 (little-endian unpacking). Why is the conversion failing?


回答1:


You can use a QDataStream to read binary data.

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);



回答2:


toLong() converts a char * digits string to long. Not bytes. And your values likely don't make the up the string "0x78563412" or its decimal equivalent. Hence the 0 result.

If you need the byte values interpreted as long you can do something like:

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

Or to access an array of bytes as long array:

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

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

Don't know whether my examples work out of the box but it should make clear the principle.

Check out this example:

char bytes[] = {255, 0};

QByteArray b(bytes, 2);

QByteArray c("255");

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

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

the output is:

0 255 
255 13618

You may need to change the byte order depending on the endianess. But it does what you need.




回答3:


you can build your qint64 with bit manipulators:

#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);
}


来源:https://stackoverflow.com/questions/36645331/how-to-unpack-32bit-integer-packed-in-a-qbytearray

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!