[英]Qt slots are not called in release mode and I blame QSharedPointer
I have a problem with signal-slot mechanism, may be that it's actually a problem with QSharedPointer
as smart pointers are new to me.我有信号槽机制的问题,可能是
QSharedPointer
的问题,因为智能指针对我来说是新的。
A little explanation of the context: TCPAssociation
is child class of LANAssociation
.上下文的一点解释:
TCPAssociation
是子类的LANAssociation
。 TCPClient
is child class to LANClient
. TCPClient
是子类LANClient
。 LANClient
has protected QSharedPointer<LANAssociation> connection
variable, TCPClient
has private QSharedPointer<TCPAssociation> conn
; LANClient
有保护QSharedPointer<LANAssociation> connection
变量, TCPClient
有私有QSharedPointer<TCPAssociation> conn
; both pointing to the same object being created in overriden pure virtual function shown below:两者都指向在覆盖的纯虚函数中创建的同一个对象,如下所示:
void TCPClient::startNewConnection(const QHostAddress &address)
{
conn.clear();
connection.clear();
conn = QSharedPointer<TCPAssociation>(new TCPAssociation(address, port, QString("Client %1").arg(hostId())));
Q_ASSERT(conn);
Q_ASSERT(connect(conn.data(), &LANAssociation::started, this, &LANClient::assoc_started, Qt::UniqueConnection));
connection = conn.staticCast<LANAssociation>();
Q_ASSERT(connection);
conn->start();
//TCPAssociation::start() { doStuff(); emit started(); }
}
The code works on Windows 10 in debug mode just fine.该代码在调试模式下在 Windows 10 上运行得很好。 In release mode on Linux,
LANClient::assoc_started
is never called.在 Linux 上的发布模式下,永远不会调用
LANClient::assoc_started
。
Now I ran my server application (above function is from a client app) in release on Windows and I can see another slot not being called in release but working just fine in debug:现在我在 Windows 上的 release 中运行了我的服务器应用程序(上面的函数来自客户端应用程序),我可以看到另一个插槽没有在 release 中被调用,但在调试中工作得很好:
void ThreadController::init(ThreadWorker *worker)
{
worker->moveToThread(&workerThread);
Q_ASSERT(connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater, Qt::UniqueConnection));
Q_ASSERT(connect(this, &ThreadController::operate, worker, &ThreadWorker::doWork, Qt::UniqueConnection));
Q_ASSERT(connect(worker, &ThreadWorker::finished, this, &ThreadController::finished, Qt::BlockingQueuedConnection));
doConnects(worker);
workerThread.start();
}
*worker
points to child class of ThreadWorker
. *worker
指向ThreadWorker
子类。 ThreadWorker::doWork()
is virtual function. ThreadWorker::doWork()
是虚函数。 It was called in debug, not in release.它是在调试中调用的,而不是在发布中调用的。 I fixed it by making
doWork()
pure virtual - now it's called both in debug and release.我通过使
doWork()
纯虚拟来修复它 - 现在它在调试和发布中都被调用。
I have also problem with QTcpSocket
and QUdpSocket
objects not emitting connected()
or readyRead()
.我也有
QTcpSocket
和QUdpSocket
对象不发出connected()
或readyRead()
。 Now I understand it's probably because I am using QSharedPointer<QAbstractSocket>
to manage them, but:现在我明白这可能是因为我使用
QSharedPointer<QAbstractSocket>
来管理它们,但是:
why the difference between debug and release?为什么调试和发布之间有区别? how to do it properly?
如何正确地做到这一点?
Should I stop using inheritance or shared pointers?我应该停止使用继承还是共享指针?
TCPAssociation::started()
is not being emitted?TCPAssociation::started()
没有被发出? LANClient::assoc_started
is also not a virtual function. LANClient::assoc_started
也不是虚函数。The expression inside the Q_ASSERT
macro will not be evaluated in non-debug build configurations: Q_ASSERT
宏中的表达式不会在非调试构建配置中计算:
Q_ASSERT()
is useful for testing pre- and post-conditions during development.Q_ASSERT()
可用于在开发过程中测试前置和后置条件。 It does nothing ifQT_NO_DEBUG
was defined during compilation.如果在编译期间定义了
QT_NO_DEBUG
则它什么也不QT_NO_DEBUG
。https://doc.qt.io/qt-5/qtglobal.html#Q_ASSERT
https://doc.qt.io/qt-5/qtglobal.html#Q_ASSERT
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.