我一直在通过qmlRegisterType玩QML应用程序和扩展,我偶然发现了一个奇怪的事情:我有2个项目。第一个产生一个带有自定义QML类型的dll,第二个是一个非常简单的应用程序,如下所示:
main.cpp:
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine(QUrl("qrc:/main.qml"));
return app.exec();
}
main.qml
import QtQuick 2.3
import QtQuick.Window 2.2
import TestLib 1.0
Window {
visible: true
width: 360
height: 360
MouseArea {
anchors.fill: parent
onClicked: {
Qt.quit();
}
}
HelloWorld {
id: hello
test: "Foo !!"
}
Text {
anchors.centerIn: parent
text: hello.test
font.pointSize: 40
}
}
当我通过Qt Creator运行我的项目时,一切正常,当我点击窗口的任何地方时,它会正常关闭。
但是现在,如果我尝试通过Visual Studio项目编译完全相同的代码(我使用Premake的特殊版本生成Visual Studio解决方案和正确处理Qt特殊文件的项目文件),那么一切都编译,运行很好,但是当我点击窗口时,我遇到了以下callstack的崩溃:
ntdll.dll!RtlFreeHeap() Unknown
kernel32.dll!HeapFree() Unknown
msvcr120.dll!free(void * pBlock) Line 51 C
TestLib.dll!000007fef7bb6d6c() Unknown
Qt5Cored.dll!QObjectPrivate::deleteChildren() Line 1936 C++
Qt5Cored.dll!QObject::~QObject() Line 1030 C++
Qt5Quickd.dll!QQuickItem::~QQuickItem() Line 2120 C++
Qt5Quickd.dll!QQuickRootItem::~QQuickRootItem() C++
Qt5Quickd.dll!QQuickRootItem::`scalar deleting destructor'(unsigned int) C++
Qt5Quickd.dll!QQuickWindow::~QQuickWindow() Line 1102 C++
Qt5Quickd.dll!QQuickWindowQmlImpl::~QQuickWindowQmlImpl() C++
Qt5Quickd.dll!QQmlPrivate::QQmlElement<QQuickWindowQmlImpl>::~QQmlElement<QQuickWindowQmlImpl>() Line 106 C++
Qt5Quickd.dll!QQmlPrivate::QQmlElement<QQuickWindowQmlImpl>::`scalar deleting destructor'(unsigned int) C++
Qt5Qmld.dll!qDeleteAll<QList<QObject * __ptr64>::const_iterator>(QList<QObject *>::const_iterator begin, QList<QObject *>::const_iterator end) Line 323 C++
Qt5Qmld.dll!qDeleteAll<QList<QObject * __ptr64> >(const QList<QObject *> & c) Line 332 C++
Qt5Qmld.dll!QQmlApplicationEnginePrivate::cleanUp() Line 64 C++
Qt5Qmld.dll!QQmlApplicationEngine::~QQmlApplicationEngine() Line 241 C++
TestApp.exe!000000013faf2630() Unknown
TestApp.exe!000000013faf4197() Unknown
我花了很多时间浏览谷歌等,但我找不到任何有用的东西。我想也许我在项目中缺少一些编译选项,Qt Creator会自动添加,但我不知道哪一个:/
我知道只看这个问题可能不足以找到解决方案,所以我准备了一个完美再现问题的小项目。如果您愿意尝试,请随时给我发消息,我会发送给您(不幸的是,我没有任何保管箱帐户或等效帐号)
提前感谢您的帮助!
答案 0 :(得分:1)
您正在使用Release CRT msvcr120.dll的至少一部分与您的调试应用程序和调试Qt dll。在同一个应用程序中混合使用Debug和Release是不安全的,因为这会创建多个独立的堆。如果在发布堆中分配内存,则无法在调试堆中释放它,反之亦然,因为这样做会破坏堆。堆损坏也不一定会在下一次分配/解除分配时导致即时崩溃,因此调试变得困难。正如您发现使用正确的CRT将解决此问题。