QVariant 反序列化给出无效值
Posted
技术标签:
【中文标题】QVariant 反序列化给出无效值【英文标题】:QVariant deserialization gives invalid value 【发布时间】:2020-02-20 13:29:10 【问题描述】:我有以下类要序列化和反序列化:
#include <QObject>
#include <QDataStream>
#include <QVariant>
/**
* @brief The type used to store the \ref CComPacket::Cmd enum
*/
using CmdType = quint8;
/**
* @brief A smart container for the TCP packets
*/
class CComPacket : public QObject
Q_OBJECT
public:
/**
* @brief Provides the command information for the packet (tells how
* the data is supposed to be parsed).
*/
enum class Cmd: CmdType
Invalid,
ReadName,
GiveName,
;
explicit CComPacket(QObject *parent = nullptr);
/**
* @brief The ostream (<<) overloading
* @param out: The data stream to which the \p cpp class is going to
* be serialized.
* @param ccp: the class to be serialized into the \p out.
* @return reference to \p out.
*/
friend QDataStream& operator<<(QDataStream& out, const CComPacket& ccp)
out << static_cast<CmdType>(ccp.m_cmd) << ccp.m_data;
return out;
/**
* @brief The istream (>>) overloading
* @param in: The serialized data that will be deserialized to the \p cpp
* @param ccp: deserialized data goes here.
* @return The \p in reference.
*/
friend QDataStream& operator>>(QDataStream& in, CComPacket& ccp)
CmdType tmp;
in >> tmp >> ccp.m_data;
ccp.m_cmd = static_cast<Cmd>(tmp);
return in;
/**
* @brief The parsing command
*/
Cmd m_cmd = Cmd::Invalid;
/**
* @brief The data to be parsed
*/
QVariant m_data;
;
我正在尝试使用此代码进行测试:
CComPacket tmp;
tmp.m_cmd = CComPacket::Cmd::GiveName;
tmp.m_data = 5.112233;
QDataStream str;
str << tmp;
CComPacket tmp2;
str >> tmp2;
调试时我看到tmp2
的m_cmd
成员被正确反序列化,但m_data
对象仍然无效。从文档中我了解到QVariant
默认支持序列化。我在这里错过了什么?
【问题讨论】:
在您的测试代码中,您有 QDataStream str 在没有设备上运行,因此它无法工作。这只是这个例子中的疏忽还是真正的代码? 这是实际代码。正如我在回答中提到的那样,我忘记为流提供实际的缓冲区。谢谢。 【参考方案1】:为了完成这项工作,我必须合并必须用作QDataStream
参数的QByteArray
,因为已经需要一个物理容器。我计划在后面的步骤中将数据序列化为字节,所以这让一切变得更容易。我添加了以下成员函数:
QByteArray serialize();
static CComPacket deserialize(QByteArray& ba);
QByteArray CComPacket::serialize()
QByteArray ba;
QDataStream ds(&ba, QIODevice::WriteOnly);
ds << *this;
return ba;
CComPacket CComPacket::deserialize(QByteArray& ba)
QDataStream ds(&ba, QIODevice::ReadOnly);
CComPacket cp;
ds >> cp;
return cp;
并且此测试代码现在可以正常工作(tmp
与 tmp2
相同):
CComPacket tmp;
tmp.m_cmd = CComPacket::Cmd::GiveName;
tmp.m_data = 5.112233;
QByteArray ba = tmp.serialize();
CComPacket tmp2 = CComPacket::deserialize(ba);
【讨论】:
以上是关于QVariant 反序列化给出无效值的主要内容,如果未能解决你的问题,请参考以下文章
没有从字符串值反序列化的字符串参数构造函数/工厂方法('2018-12-14')
使用 Jackson 从 XML 到 POJO 的反序列化问题:没有从字符串值反序列化的字符串参数构造函数/工厂方法
反序列化错误 : 不能构造Dto的实例(尽管至少有一个Creator存在):不能从对象值反序列化。
Jackson MismatchedInputException(没有从字符串值反序列化的字符串参数构造函数/工厂方法)