QDataStream正在成为Readonly

时间:2016-06-16 05:33:04

标签: c++ qt qdatastream

我有两个名为IPCBase和DispatchData的类。现在我想将QDataStrean Object drom IPCBase传递给DispatchData。首先,我尝试使用Connect Statement直接发送它。但它给出的错误就像QDataStream对象没有在QRegisterMatatype中注册。

编辑::我也提到了这个链接

When, where and why use namespace when registering custom types for Qt

所以我做了类似

的事情
typedef QDataStream* myDataStrem;
Q_DECLARE_METATYPE(myDataStrem)

然后在另一个类(DispatchData)中连接语句

connect(mpThrIPCReceiver, SIGNAL(dispatchReadData(const int&, myDataStrem)),
        this, SLOT(onIPCDataReceived(const int&, myDataStrem)));

onIPCDataReceived Slot

void DispatchData::onIPCDataReceived(const int& msgType, myDataStrem dataReceived)
{

//    dataReceived >> str1;     Here it is giving error
//    qDebug()<<"is"<<str1;

    MemberFuncPointer f = mIPCCommandMapper.value(msgType);
    (this->*f)(*dataReceived);              
 //This is function pointer which will rout it to respective function depending on the Message type.

然后它会来到这里

void DispatchData::onStartCountingCycle(QDataStream &dataReceived)
{
    int data = 0;
    dataReceived >> data;     //Here it is crashing

    //Giving error like
    //pure virtual method called
    //terminate called without an active exception

    // I have debugged it and here dataReceived is becoming Readonly.
}

1 个答案:

答案 0 :(得分:0)

看起来你正在绕过一个悬垂的指针:到接收线程到达时,数据流似乎不再存在。即使您在源对象中延长其生命周期,通过信号槽连接传递原始指针也是一个坏主意。如果源类可能在接收器线程有待处理的时隙调用时消失,那么您仍然会在接收器处使用悬空指针。绕过QSharedPointerstd::shared_ptr

可以获得最佳服务

以下工作,您当然可以使用共享指针中的任何类型。

#include <QtCore>
#include <cstdio>

struct Class : public QObject {
   Q_SIGNAL void source(QSharedPointer<QTextStream>);
   Q_SLOT void destination(QSharedPointer<QTextStream> stream) {
      *stream << "Hello" << endl;
   }
   Q_OBJECT
};
Q_DECLARE_METATYPE(QSharedPointer<QTextStream>)

int main(int argc, char ** argv) {
   QCoreApplication app{argc, argv};
   Class c;
   c.connect(&c, &Class::source, &c, &Class::destination, Qt::QueuedConnection);
   auto out = QSharedPointer<QTextStream>(new QTextStream(stdout));
   emit c.source(out);
   QMetaObject::invokeMethod(&app, "quit", Qt::QueuedConnection);
   *out << "About to exec" << endl;
   return app.exec();
}
#include "main.moc"

输出:

About to exec
Hello

在现代Qt(至少5.6)上,在这种情况下,您不需要致电qRegisterMetatype

使用std::shared_ptr

// https://github.com/KubaO/stackoverflown/tree/master/questions/datastream-pass-37850584
#include <QtCore>
#include <cstdio>
#include <memory>

struct Class : public QObject {
   Q_SIGNAL void source(std::shared_ptr<QTextStream>);
   Q_SLOT void destination(std::shared_ptr<QTextStream> stream) {
      *stream << "Hello" << endl;
   }
   Q_OBJECT
};
Q_DECLARE_METATYPE(std::shared_ptr<QTextStream>)

int main(int argc, char ** argv) {
   QCoreApplication app{argc, argv};
   Class c;
   c.connect(&c, &Class::source, &c, &Class::destination, Qt::QueuedConnection);
   auto out = std::make_shared<QTextStream>(stdout);
   emit c.source(out);
   QMetaObject::invokeMethod(&app, "quit", Qt::QueuedConnection);
   *out << "About to exec" << endl;
   return app.exec();
}
#include "main.moc"