我正在开发基于桌面(Windows 7)的应用程序,并使用Qt Creator v 5.6.0开发本程序。 我有一个非常奇怪的问题,即
我的程序在DEBUG模式下崩溃,但在RELEASE模式下工作正常。
如果处于DEBUG模式,并且我放置了断点来查找崩溃的原因,那么它不会崩溃:它可以正常工作。但如果我没有提出任何断点,那么它会在下面的代码中崩溃:
项目背景: 我的项目包括从系统通信端口连接的设备读取的功能,并将数据传输到MainWindow UI进行显示。由于要与通信端口通信,我们必须使用第三方库,因此我没有使用更简单易用的QtSerial端口类。
代码设计: 类MainClass:在这个类中,我们创建了一些表单来显示从设备读取的数据。
Class TestClass:此类将处理与系统串行端口连接的设备的所有通信,并使用第三方库。该类还具有while循环,用于从串行端口连接的设备读取数据。
由于Test Class正在使用while循环。所以我们决定让Test Class在不同的Thread中运行。
在MainClass构造函数中创建Thread的代码:
MainClass::MainClass (QWidget *parent) : QDialog(parent),
ui(new Ui::Analzyer)
{
............................
............................
workerThread = new QThread;
testClassObject = new TestClass(); // Declared in HeaderFile of MainClass
if((workerThread != NULL) && (testClassObject != NULL))
{
workerThread ->moveToThread(testClassObject );
connect(workerThread , SIGNAL(started()), testClassObject, SLOT(SomeFunc()));
connect(testClassObject, SIGNAL(exit()), workerThread , SLOT(quit()));
connect(testClassObject, SIGNAL(exit()), testClassObject, SLOT(deleteLater()));
connect(workerThread , SIGNAL(finished()), workerThread , SLOT(deleteLater()));
// connectToPort Signal is emitted when User clicks the pushbutton from // Main class UI
connect(this, SIGNAL(connectToPort(QString)), testClassObject, SLOT(openPort(QString)));
}
}
崩溃代码:
void TestClass::openPort(const QString portName)
{
// Here portName is say : "Appliance Interface v2"
quint32 param2 = getParam2ForPortName(portName);
qint16 portNumber = 0;
QByteArray portNameByteArray = portName.toLatin1();
const char *portNameToOpen = portNameByteArray.data();
// Program crashed when return from this function
if(func1(portNameToOpen , param2, 10 , &portNumber) == true)
{
......................
......................
}
}
在这里,我添加了一些qDebug()并发现我的代码在返回时崩溃或调用func1(),它在插槽OpenPort()中被调用。下面是func1()的原型
bool func1 (const char portDescription[], uInt32 param2,
uInt16 length, Int16 * portNr);
因为,func1()是库代码的一部分。所以我无法检查函数func1()的定义。我可以保证func1()中没有问题,因为它在不同的基于java的项目中使用它可以工作。
我在项目上做了一些调试并注意到当在DEBUG模式下使用BreakPoints运行时比在QT线程调试窗口中运行时我可以看到我连接的Slot但是当我没有放置任何breakPoint而不是我的代码崩溃并且在Qt中线程调试窗口我看不到我连接的插槽
因此,它看起来主要类和openPort Slot的测试类之间的连接问题。
但是当我在operPort()函数中放置断点时,我无法理解ttt在Qt线程调试窗口中看到我的openPort Slot但是在Qt线程调试窗口和程序崩溃中看不到断点而不是openPort Slot
请建议,
答案 0 :(得分:0)
我可以确保func1()中没有问题,因为它在不同的基于java的项目中使用它可以工作。
等等,是func1()C ++还是Java?
另外,你怎么能确定它有效呢?
获取库源代码,自行编译,然后在其中进行调试
而且,只是为了确保在调试时检查变量的值,并在不调试时检查qDebug()
答案 1 :(得分:0)
我为回复自己的帖子而道歉,但经过对StackOverflow和google的大量讨论。我能够解决问题。
解决问题: 我更改了SLOT(openPort),如下所述:
Connect(this, SIGNAL(connectToPort(QString)), testClassObject, SLOT(openPort(QString)), Qt::DirectConnection);
即使用" Qt:DirectConnection"方法。如果我们不指定连接方法,则直接方法将自动用于SAME线程上的对象之间的连接。 从那以后,我们为TestClass创建了一个新的QThread,并使用了一个可能不是线程安全的thirdParty库。 所以使用" Qt :: DirectConnection"使openPort()Slot在MainClass Thread中运行。基本上,它就像发出信号一样直接调用插槽方法"直接"。