将具有已知 QMetaType::Type 的 QByteArray 反序列化为 QVariant

Posted

技术标签:

【中文标题】将具有已知 QMetaType::Type 的 QByteArray 反序列化为 QVariant【英文标题】:Deserializing QByteArray with known QMetaType::Type into QVariant 【发布时间】:2020-08-07 10:17:08 【问题描述】:

我有一个包含变量原始数据的QByteArray。 描述变量的QMetaType::Type 是已知的。

我想将此变量反序列化为QVariant

使用以下输入:

QByteArray bytes; // Consider it initialized
QMetaType::Type type; // Same

到目前为止我的尝试都没有成功:

QVariant varbytes;
var.convert(type); // Does not work, apparently QVariant expects bytes to be a string representation of the variable
QDataStream ds(bytes, QIODevice::ReadOnly);
QVariant var;
ds >> var; // Does not work because bytes does not come from the serialization of a QVariant (especially, it lacks type information)

我无法更改我的输入或输出类型:

输入必须QByteArrayQMetaType::Type类型。 输出必须QVariant类型

例子:

//Inputs
QByteArray bytes =  0x12, 0x34, 0x56, 0x78 ;
QMetaType::Type type = QMetaType::UInt; // Suppose the size of unsigned int is 4 bytes (could be 2)
// Note: this is an example, in pratice I have to manage many types, including double

//Expected output:
QVariant var = deserialize(bytes, type);
// var.type() == QMetaType::UInt
// var.toUInt() == 305419896 (== 0x12345678)

【问题讨论】:

你为什么不干脆这样做:auto v = QVariant(bytes.toUInt());? 因为unsigned int 不会是我收到的唯一类型,这只是一个示例。我想避免单独管理每种类型。 您找到可行的解决方案了吗? 【参考方案1】:

面对同样的问题,我使用提供的类型 id 直接通过其 data() 方法从 QByteArray 构造 QVariant

QByteArray bytes; // Consider it initialized
QMetaType::Type type; // Same
QVariant result(type.id(),bytes.data());

如果构造失败,你最终会得到一个无效的QVariant,但到目前为止,对于我的类型来说,它运行良好。

【讨论】:

【参考方案2】:

您可以写信给unsigned int,然后将其转换为QVariant

    const char data[] =  0x12, 0x34, 0x56, 0x78 ;
    QByteArray bytes  QByteArray::fromRawData( data, 4) ;

    QDataStream s &bytes, QIODevice::ReadOnly;
    //write out the data to uint
    unsigned int x;
    s >> x;

    //create a Qvariant from it
    QVariant varx;

    qDebug () << "x: " << x;                       //305419896
    qDebug () << "variant: " << var;               //QVariant(uint, 305419896)
    qDebug () << "variant uint: " << var.toUInt(); //305419896

或者你也可以直接构造一个QVariant

    auto v = QVariant(bytes.toHex().toUInt());
    //auto v = QVariant(bytes.toUInt());            //this will not work
    qDebug () << "Bytes to uint; " << v.toUInt(); //305419896

【讨论】:

我宁愿避免转换为真实类型,然后转换为QVariant。在实践中,我会收到许多不同类型的输入。必须管理每种类型会很乏味。使用toHex() 是否适用于任何类型? QByteArray 包含原始字节,所以是的,toHex() 将始终有效 也许我没说清楚,抱歉,我的意思是,我能不能从toHex() 的结果转换成任何类型? 您可以根据需要从QByteArray 转换为any 类型。所以是的,但是如果 TYPE 是用户定义的类型而不是简单的 int、short、long 等,则您必须自己进行序列化。

以上是关于将具有已知 QMetaType::Type 的 QByteArray 反序列化为 QVariant的主要内容,如果未能解决你的问题,请参考以下文章

union-find算法探究

ffmpeg 将 avi 拆分为具有已知帧速率的帧

将 DLL 加载到具有已知唯一公共接口的单独 AppDomain 中

CryptoRSA

数据结构:已知递增有序的单链表A,B

如何为已知行数创建具有无限列的 Angular Material Design 表?