Create object in another object
-
I would like to separate above task form others. This project is for learning programming purposes only.
In my example using thread it is a mistake ? -
I would like to separate above task form others. This project is for learning programming purposes only.
In my example using thread it is a mistake ?@Damian7546 said in Create object in another object:
In my example using thread it is a mistake ?
You should avoid threads if they are not needed as it is easy to do mistakes and the code becomes more complex. As I wrote: Qt is an asynchronous framework, that means you usually do not need threads. QSerialPort is also asynchronous - you can use it without threads and it will still not block your main thread. Threads are usually used to move heavy calculations to other threads, but I don't see any heavy calculations in your code.
-
I would like to separate above task form others. This project is for learning programming purposes only.
In my example using thread it is a mistake ?@Damian7546 said in Create object in another object:
This project is for learning programming purposes only
Then start with writing clean code without threads. Write a good handler class to handle your incoming data. Once this is done this class can be easily moved into a separate thread if really needed.
-
anyway, can anyone demonstrate why the above code doesn't work when created from the constructor? but works with the
main.cpp
one? -
anyway, can anyone demonstrate why the above code doesn't work when created from the constructor? but works with the
main.cpp
one?@Damian7546 If your application crashes then the first thing to do is: use the debugger.
So, please run your app in debugger and post the stack trace after the crash here... -
Your code crashes in the dtor of RfidSerialWorker (if doWork() would reach it's end), also it's using a blocking approach instead signals and slots to wait for data, the strange
while(1)
- loop does never exits and at last ít's accessing outFrameQueue from two different threads without proper locking mechanisms (and before you ask - read and understand at least https://doc.qt.io/qt-6/threads-synchronizing.html before fiddling around with threads for no reason). -
@Christian-Ehrlicher so I will do like you propose.
-
I think that no a problem with thread.
I remove thread and create my object like below:
QQueue<RfidFrame*> outFrameQueue; RfidSerialWorker *rfidSerialWorker = new RfidSerialWorker(&outFrameQueue); RfidFrameProcessor *rfidFrameProcessor = new RfidFrameProcessor(&outFrameQueue); connect(rfidSerialWorker, SIGNAL(frameReceived(RfidFrame*)), rfidFrameProcessor, SLOT(FrameIncoming(RfidFrame*))); connect(rfidFrameProcessor, SIGNAL(frameSend()), rfidSerialWorker, SLOT(frameToSend())); rfidSerialWorker->initSerialPort(); //tests - try send frame cyclically QTimer *timer = new QTimer(this); QObject::connect(timer, SIGNAL(timeout()), rfidFrameProcessor , SLOT(update_power_ind())); timer->start(2000);
Function which one try send frame is below:
void RfidFrameProcessor::update_power_ind() { readSourceRSx(1,9); } void RfidFrameProcessor::readSourceRSx(quint8 addr, quint8 source) { QByteArray data; data.append(source); RfidFrame *frameToSend = new RfidFrame(addr, C_ReadSourceRSx, data); qDebug() << "Get lenght from frameToSend: " << frameToSend->GetDataLength(); m_outFrameQueue->enqueue(frameToSend); emit frameSend(); }
and problem is in the same step:
m_outFrameQueue->enqueue(frameToSend);
despite the fact that inframeToSend
I have data like you can see in below in Application Output. -
I think that no a problem with thread.
I remove thread and create my object like below:
QQueue<RfidFrame*> outFrameQueue; RfidSerialWorker *rfidSerialWorker = new RfidSerialWorker(&outFrameQueue); RfidFrameProcessor *rfidFrameProcessor = new RfidFrameProcessor(&outFrameQueue); connect(rfidSerialWorker, SIGNAL(frameReceived(RfidFrame*)), rfidFrameProcessor, SLOT(FrameIncoming(RfidFrame*))); connect(rfidFrameProcessor, SIGNAL(frameSend()), rfidSerialWorker, SLOT(frameToSend())); rfidSerialWorker->initSerialPort(); //tests - try send frame cyclically QTimer *timer = new QTimer(this); QObject::connect(timer, SIGNAL(timeout()), rfidFrameProcessor , SLOT(update_power_ind())); timer->start(2000);
Function which one try send frame is below:
void RfidFrameProcessor::update_power_ind() { readSourceRSx(1,9); } void RfidFrameProcessor::readSourceRSx(quint8 addr, quint8 source) { QByteArray data; data.append(source); RfidFrame *frameToSend = new RfidFrame(addr, C_ReadSourceRSx, data); qDebug() << "Get lenght from frameToSend: " << frameToSend->GetDataLength(); m_outFrameQueue->enqueue(frameToSend); emit frameSend(); }
and problem is in the same step:
m_outFrameQueue->enqueue(frameToSend);
despite the fact that inframeToSend
I have data like you can see in below in Application Output.@Damian7546 said in Create object in another object:
and problem is in the same step
And again: is m_outFrameQueue a valid pointer?
-
@Damian7546 said in Create object in another object:
and problem is in the same step
And again: is m_outFrameQueue a valid pointer?
@jsulm In my opinion yes, but I am beginner.... Please explain me.
.hclass RfidFrameProcessor : public QObject { Q_OBJECT public: explicit RfidFrameProcessor(QQueue<RfidFrame*> *outFrameQueue, QObject *parent = nullptr); private: QQueue<RfidFrame*> *m_outFrameQueue; }
.cpp
RfidFrameProcessor::RfidFrameProcessor(QQueue<RfidFrame*> *outFrameQueue,QObject *parent) : QObject(parent) { m_outFrameQueue = outFrameQueue; }
-
@jsulm In my opinion yes, but I am beginner.... Please explain me.
.hclass RfidFrameProcessor : public QObject { Q_OBJECT public: explicit RfidFrameProcessor(QQueue<RfidFrame*> *outFrameQueue, QObject *parent = nullptr); private: QQueue<RfidFrame*> *m_outFrameQueue; }
.cpp
RfidFrameProcessor::RfidFrameProcessor(QQueue<RfidFrame*> *outFrameQueue,QObject *parent) : QObject(parent) { m_outFrameQueue = outFrameQueue; }
@Damian7546 said in Create object in another object:
m_outFrameQueue = outFrameQueue;
I laready asked that before: is outFrameQueue a valid pointer?
-
Ok,
I create in this way:QQueue<RfidFrame*> outFrameQueue; RfidSerialWorker *rfidSerialWorker = new RfidSerialWorker(&outFrameQueue); RfidFrameProcessor *rfidFrameProcessor = new RfidFrameProcessor(&outFrameQueue);
But in class
Q_OBJECT public: explicit RfidFrameProcessor(QQueue<RfidFrame*> *outFrameQueue, QObject *parent = nullptr); private: QQueue<RfidFrame*> *m_outFrameQueue;
-
I think that no a problem with thread.
I remove thread and create my object like below:
QQueue<RfidFrame*> outFrameQueue; RfidSerialWorker *rfidSerialWorker = new RfidSerialWorker(&outFrameQueue); RfidFrameProcessor *rfidFrameProcessor = new RfidFrameProcessor(&outFrameQueue); connect(rfidSerialWorker, SIGNAL(frameReceived(RfidFrame*)), rfidFrameProcessor, SLOT(FrameIncoming(RfidFrame*))); connect(rfidFrameProcessor, SIGNAL(frameSend()), rfidSerialWorker, SLOT(frameToSend())); rfidSerialWorker->initSerialPort(); //tests - try send frame cyclically QTimer *timer = new QTimer(this); QObject::connect(timer, SIGNAL(timeout()), rfidFrameProcessor , SLOT(update_power_ind())); timer->start(2000);
Function which one try send frame is below:
void RfidFrameProcessor::update_power_ind() { readSourceRSx(1,9); } void RfidFrameProcessor::readSourceRSx(quint8 addr, quint8 source) { QByteArray data; data.append(source); RfidFrame *frameToSend = new RfidFrame(addr, C_ReadSourceRSx, data); qDebug() << "Get lenght from frameToSend: " << frameToSend->GetDataLength(); m_outFrameQueue->enqueue(frameToSend); emit frameSend(); }
and problem is in the same step:
m_outFrameQueue->enqueue(frameToSend);
despite the fact that inframeToSend
I have data like you can see in below in Application Output.@Damian7546 said in Create object in another object:
QQueue<RfidFrame*> outFrameQueue; RfidSerialWorker *rfidSerialWorker = new RfidSerialWorker(&outFrameQueue); RfidFrameProcessor *rfidFrameProcessor = new RfidFrameProcessor(&outFrameQueue); ... timer->start(2000);
If I understand your code right.
QQueue<RfidFrame*> outFrameQueue
is a local variable in some method? But once you have set off the timer you exit that method, right? So theQQueue<RfidFrame*> outFrameQueue
goes out of scope and gets destroyed at that point. Yet you have passed that queue as a parameter toRfidSerialWorker
/RfidFrameProcessor
, they have set am_outFrameQueue
to point to that queue passed in, it is no longer valid, but they still use it => disaster. Is my analysis correct for your code?I'm not sure, but it sounds like your
QQueue<RfidFrame*> outFrameQueue;
should not be local variable in a method but rather a persistent member variable? -
Thanks
QQueue<RfidFrame*> outFrameQueue
i wolud like to pass frame to send beetwenRfidSerialWorker
andRfidFrameProcessor
.@JonB said in Create object in another object:
I'm not sure, but it sounds like your QQueue<RfidFrame*> outFrameQueue; should not be local variable in a method but rather a persistent member variable?
Exactly. But how do this ?
-
Thanks
QQueue<RfidFrame*> outFrameQueue
i wolud like to pass frame to send beetwenRfidSerialWorker
andRfidFrameProcessor
.@JonB said in Create object in another object:
I'm not sure, but it sounds like your QQueue<RfidFrame*> outFrameQueue; should not be local variable in a method but rather a persistent member variable?
Exactly. But how do this ?
@Damian7546 said in Create object in another object:
But how do this ?
Make outFrameQueue member variable instead of local variable.
-
sure!! Thank you !