qt - ¿Cómo desempaquetar un entero de 32 bits empaquetado en un QByteArray?
type-conversion qt5 (3)
Puede usar QDataStream
para leer datos binarios.
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);
Estoy trabajando con comunicación en serie, y recibo enteros de 32 bits en un QByteArray
, empaquetados en 4 bytes separados (little-endian). Intento descomprimir el valor de los 4 bytes utilizando QByteArray::toLong()
pero falla la conversión y devuelve el número incorrecto:
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
El valor esperado unpacked_value es 0x78563412 (desempaquetado de little-endian). ¿Por qué está fallando la conversión?
puedes construir tu qint64 con manipuladores de bits:
#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);
}
toLong()
convierte una string
* dígitos en larga. No bytes Y sus valores probablemente no suban la cadena "0x78563412" o su equivalente decimal. De ahí el 0 resultado.
Si necesita los valores de bytes interpretados como largos, puede hacer algo como:
long value;
value == *((long*)packed_bytes.data());
O para acceder a una matriz de bytes como larga matriz:
long * values;
values == (long*)packed_bytes.data();
values[0]; // contains first long
values[1]; // contains second long
...
No sé si mis ejemplos funcionan de la caja pero debe aclarar el principio.
Mira este ejemplo:
char bytes[] = {255, 0};
QByteArray b(bytes, 2);
QByteArray c("255");
qDebug() << b.toShort() << c.toShort();
qDebug() << *((short*)b.data()) << *((short*)c.data());
la salida es:
0 255
255 13618
Es posible que deba cambiar el orden de bytes en función de la endianess. Pero hace lo que necesitas.