2016-06-16 2 views
0

IPCBaseとDispatchDataの2つのクラスがあります。今度は、QDataStreanオブジェクトdrom IPCBaseをDispatchDataに渡したいと思います。まず、Connect Statementを使用して直接送信しようとしました。しかし、それはQDataStreamオブジェクトがQRegisterMatatypeに登録されていないようなエラーを出しています。QDataStreamがReadonlyになっています

編集::私は、だから私は

typedef QDataStream* myDataStrem; 
Q_DECLARE_METATYPE(myDataStrem) 

のようなものを行って、その後、別のクラス(DispatchData)

connect(mpThrIPCReceiver, SIGNAL(dispatchReadData(const int&, myDataStrem)), 
     this, SLOT(onIPCDataReceived(const int&, myDataStrem))); 
に声明を接続している

同様

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

をこのリンクを参照されています

onIPCData受信スロット

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. 
} 
+0

私はあなたを助けることができますが、機能の例を提供してください! – Roland

+1

スレッドを使用しているようです。そのため、自動的に接続がキューに入れられます。その場合は、あなたに伝えられるメッセージとして 'QDataStream'のために[' qRegisterMetatype'](http://doc.qt.io/qt-5/qmetatype.html#details)を呼び出さなければなりません。しかし、これはまだ私にとって非常に奇妙に思えます。どうして 'QDataStream'オブジェクトをスレッド間で送信していますか?実際に何をしようとしているのかを説明してください。これは私にとって[XY問題](http://xyproblem.info)のようです。 – thuga

+0

@thugaここに 'qRegisterMetatype'は必要ありません。 –

答えて

0

来るあなたはダングリングポインタの周りに渡しているように思える:データストリームは、受信スレッドは、それに到達する時間によってもはや存在しないようです。たとえあなたがソースオブジェクトでその存続期間を延長したとしても、シグナルスロット接続を通して生ポインタを渡すことは悪い考えです。受信側のスレッドが保留中のスロットコールを持っている間にソースクラスが消えてしまうかもしれませんが、それでも受信側ではダングリングポインタを使用しています。あなたはQSharedPointerまたはstd::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" 

出力:現代のQt(少なくとも5.6)で

About to exec 
Hello 

、あなたは、この場合には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" 
関連する問題