RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 797744
Accepted
asianirish
asianirish
Asked:2020-03-14 00:45:29 +0000 UTC2020-03-14 00:45:29 +0000 UTC 2020-03-14 00:45:29 +0000 UTC

从 QVariant 对象获取二进制数据。将整数转换为 QByteArray 时,会出现额外的字节

  • 772

我将一个整数转换为QVariant一个对象QByteArray,以便这个数字有一个字节表示。

我愿意:

#include <QDebug>
#include <QByteArray>
#include <QDataStream>


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    qDebug() << "size of int:" << sizeof(int);
    QVariant var((int)0xF123);
    QByteArray data(sizeof(int),(char)0);
    qDebug() << "data before all:" << data.toHex();

    QDataStream ds(&data,QIODevice::WriteOnly);
    ds << var;

    qDebug() << "size of data:" << data.size();
    qDebug() << "var to binary byte array:" << data./*right(4).*/toHex();

    return 0;
}

在输出我得到:

size of int: 4
data before all: "00000000"
size of data: 9
var to binary byte array: "00000002000000f123"

九个字节而不是四个字节是从哪里来的?

当然,您可以在将类型var发送到 之前显式转换类型QDataStream,如下所示:

ds << var.toInt();

但是在一个真正的程序中,我事先并不知道 in 的类型QVariant,并且我不想switch通过枚举所有可能的数字typeId变量var来做到这一点,而是优雅地做到这一点。

本质上,任务归结为从对象中获取原始数据QVariant及其大小(实际上,大小可以通过 获得typeId,但是你需要用一个长开关检查,值QVariant::type(),此外,要考虑到QMetaType::Int不同的环境它可以有不同的大小,你还必须比较sizeof(int)

PS我发现了一个关于该主题的有趣页面: https ://bugreports.qt.io/browse/QTBUG-35510?page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel&showAll=true

c++
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    Ariox
    2020-03-14T04:14:03Z2020-03-14T04:14:03Z

    QDataStream有自己的数据格式,接近数字的硬件表示,但又有所不同。如果您QByteArray通过写入QDataStream,则需要通读它(通过 的另一个实例QDataStream)。并且不清楚为什么将 0 放在数组的开头 - 这显然不合适,您不应该将 data 与 data 混合QDataStream。

    它应该是这样的:

    QByteArray data;
    
    {
       QDataStream out(&data, QIODevice::WriteOnly);
    
       int value = 0xF123;
       out << value;
    }
    // Предполагаем, что мы записали данные в файл, а потом считали их:
    QByteArray inputData = data;
    {
       QDataStream in(&data, QIODevice::ReadOnly);
    
       int value;
       in >> value; // тут ещё хорошо бы проверять на ошибки
       qDebug() << QString::number(value, 16);
    }
    

    如果您想使用“原始”数据 - 不要使用QDataStream

    QByteArray data;
    {
       int value = 0xF123;
       data.append(reinterpret_cast<char*>(&value), sizeof(value));
    }
    {
       int value = *reinterpret_cast<int*>(data.data());
       qDebug() << QString::number(value, 16);
    
       // или
       qDebug() << data.toHex();
    }
    
    • 1
  2. asianirish
    2020-03-14T19:15:11Z2020-03-14T19:15:11Z

    受到@Ariox 评论的启发(我借此机会表示感谢,谢谢)和以下信件,我找到了这样一个犹太/非犹太(强调必要的)解决方案:

    修改后的示例如下所示:

    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        QVariant var((int)0xF123);
    
        qDebug() << "source number:" << QString::number(var.toInt(), 16);
    
        QMetaType mt(var.type());
    
        char *buf;
        buf = (char*)var.constData();
    
        QByteArray ba; //тоже сойдет: ((char*)buf, QMetaType::sizeOf(var.type()));
        ba.setRawData(buf, QMetaType::sizeOf(var.type()));
    
        qDebug() << ba.toHex();
    
        QVariant target(var.type(), ba.data());
        qDebug() << "target number:" << QString::number(target.toInt(), 16);
    
        return 0;
    }
    

    也就是说,我使用了一个未记录但开源的QVariant::constData.

    QByteArray不需要“犹太洁食”(但不正确)的用法。事实证明, in 中的类型的大小QVariant很容易通过QMetaType::sizeOf

    恕我直言QVariant::constData,尽管担心它的“不安全性”,但它应该被留下并记录在案,因为 C++ 语言本身实际上是不安全的,它允许你在脚下射击并将很多责任放在程序员自己身上,为什么剥夺程序员的所有机会QVariant,否则某些任务没有解决?

    PS也许将来他们会打开并QVariant::convert(const int t, void ptr) const记录QVariant::constData

    • 0

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5