I'm trying to pass a custom class pointer (With using polymorphism) to another by using signal slot mechanism. Basically I have a base class and multiple derived classes (They are not extended from QObject) and I'm trying to pass the base class to another thread by using signal slot mechanism as described in below example. When I do that I can succesfully transfer the base class pointer to another thread but when I try to downcast it , or call the virtual method I got sigsegv exception . I've searched through lots of articles but wasnt able to find a proper solution, does anyone has experienced such problem before?
This is the part which I've created the worker threads
qRegisterMetaType<SecondMessage>();
for (const auto& receiver : glimpseReceivers) {
QThread *thread = new QThread();
receiver->moveToThread(thread);
QObject::connect(thread, SIGNAL(started()), receiver.get(), SLOT(start()));
QObject::connect(receiver.get(), SIGNAL(finished()), thread, SLOT (quit()));
QObject::connect(receiver.get(), SIGNAL (finished()), receiver.get(), SLOT (deleteLater()));
QObject::connect(thread, SIGNAL(finished()), thread, SLOT (deleteLater()));
QObject::connect(receiver.get(),&MAGlimpseReceiver::sequenceNumberReceived,this,&MAItchManager::sequenceReceived);
QObject::connect(receiver.get(),&MAGlimpseReceiver::glimpseDataSignal,this,&MAItchManager::itchDataReceived);
thread->start();
threadList.push_back(thread);
}
This is the signal which is called from worker thread to main thread:
void MAGlimpseReceiver::glimpseDataReceived(ITradeMessagePtr tradeMessage) {
if (tradeMessage != nullptr) {
spdlog::debug("Glimpse Data Received For Market:{} Part:{} Type:{}",configuration.marketId,configuration.partId,tradeMessage->getType());
emit glimpseDataSignal(tradeMessage.get(),int(configuration.marketId),configuration.partId);
}
}
This is the slot in the main thread which receives the signal and try to use the virtual method
void MAItchManager::itchDataReceived(ITradeMessage* tradeMessage,int marketId,int partId) {
spdlog::debug("Itch Data Received for Market: {} Part: {} Type:{}",marketId,partId,char(tradeMessage->getType()));
if (tradeMessage->isValidMessage()) {
auto itchPackage = std::make_shared<ItchPackage>();
ItchMessage *itchMessage = tradeMessage->getItchMessage();
itchPackage->market = MarketType (marketId);
itchPackage->part = partId;
itchPackage->itchMessage = itchMessage;
if (callBack != nullptr) {
callBack(itchPackage.get());
}
} else {
spdlog::error("Unknown Trade Message Type:{}",tradeMessage->getType());
}
}
And this is one of the example of base and derived classes which I'm trying to transfer to main thread. Base class:
class ITradeMessage {
public:
ITradeMessage() {
}
ITradeMessage(const char* message) {
}
virtual ~ITradeMessage() {
}
ItchMessageType getType() const {
return type;
}
virtual ItchMessage * getItchMessage() = 0;
bool isValidMessage() const {
return validMessage;
}
protected:
ItchMessageType type = ItchMessageType::Msg_None;
bool validMessage = false;
};
using ITradeMessagePtr = std::shared_ptr<ITradeMessage>;
Derived Class:
class SecondMessage: public ITradeMessage {
public:
SecondMessage() = default;
SecondMessage(const char* message);
SecondMessage(const SecondMessage& obj);
~SecondMessage() = default;
friend std::ostream& operator<<(std::ostream&, const SecondMessage&);
ItchMessage *getItchMessage();
};
Q_DECLARE_METATYPE(SecondMessage); //Compiler gives this warning but still compiles: Excess elements in struct initializer
using SecondMessagePtr = std::shared_ptr<SecondMessage>;
MAGlimpseReceiver::glimpseDataReceived
is passing the raw pointer managed by a shared_ptr across a queued connection. It's possible the shared_ptr has gone out of scope and deleted the managed memory before the receiving slot gets invoked. – G.M." I try to pass the shared_ptr directly, qt doesnt trigger the signal/slot mechanism"
? If that's the case then there should be an error message of some sort at the console. Essentially you need something likeqRegisterMetaType<std::shared_ptr<ITradeMessage>>()
to allow you to enqueue variables of that type. – G.M.