运行时错误:"必须在QWidget之前构建一个QApplication"从使用静态Qt

时间:2017-11-07 17:06:12

标签: c++ qt dll static-libraries

我从VS2015命令行构建了一个静态版本的Qt,其中包含以下内容:

..\Src\configure -prefix E:\Qt\Qt5.9.1\5.9.1\QtStatic -static -static-runtime -nomake tests -nomake examples -debug-and-release -developer-build -opensource -confirm-license -opengl desktop

我使用Cmake来构建我的主应用程序和一个dll,使用/ MTd选项并链接(在调试模式下)所有" * d.lib" Qt / lib和/ plugins / platforms目录中的文件以及C:/ Program Files(x86)/ Microsoft SDKs / Windows / v7.1A / Lib / x64文件夹。

我的主要职能:

#include "myWindowClass.h"
#include <QApplication.h>
int main(int argc, char **argv) {
    QApplication app(argc, argv);
    myWindowClass *mwc = new myWindowClass();
    mwc->show();
    return app.exec();
}

myWindowClass.h(STATIC_BUILD在Cmake中定义):

#pragma once
#include <QMainWindow.h>
#include "ui_mainWindow.h"
#include <QtPlugin>
#include <QLibrary>
#include "myDllClass.h"

#ifdef STATIC_BUILD
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)
#endif

typedef MyDllClass* (*MyDll)();

namespace Ui {
    class myWindowClass;
}

class myWindowClass : public QMainWindow {
    Q_OBJECT
public:
    myWindowClass(QWidget *parent = 0);
    ~myWindowClass() {
        delete ui;
    }

public slots:
    void launchMyDialog();
    void loadMyDll();

private:
    Ui::MainWindow *ui;
    QLibrary *lib;
    MyDllClass *myc;
};

myWindowClass.cpp:

#include "myWindowClass.h"

myWindowClass::myWindowClass(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

void myWindowClass::launchMyDialog() {
    if (lib)
        if (lib->isLoaded())
            myc->launchDialog();
}

myWindowClass::loadMyDll() {
    lib = new QLibrary("MyDLL.dll");
    lib->load();
    if (lib->isLoaded()) { // Library is found to be loaded
        auto create = (MyDll)lib.resolve("Create");
        if (create)  // Create resolves successfully
            myc = create(); // create executes successfully
    }

}

我使用Qt Designer构建了一个mainWindow.ui,它具有连接到loadMyDll()和launchMyDialog()函数的按钮。

在myDllClass.h中:

#if defined (WIN32) && defined (BUILD_SHARED_LIBS)
#if defined (_MSC_VER)
#pragma warning(disable: 4251)
#endif
#if defined(MyDLL_EXPORT)
#define  MYLIB_EXPORT __declspec(dllexport)
#else
#define  MYLIB_EXPORT __declspec(dllimport)
#endif
#else
#define MYLIB_EXPORT
#endif

struct MyDllClass {
    virtual void launchDialog() = 0;
};

class MyClass : public MyDllClass
{
public:
    MyClass() {}
    ~MyClass() {}
    void launchDialog();
};

在myDllClass.cpp中:

#include "myDllClass.h"
#include "MyDialog.h"

MyClass::launchDialog() {
    myDialogClass *pDllDialog = new myDialogClass(); // Runtime error  "QWidget: must construct a QApplication before a QWidget"
    pDllDialog->raise();
    pDllDialog->activateWindow();
    pDllDialog->exec();
}

extern "C" MYLIB_EXPORT MyDllClass * Create() {
    return new MyClass();
}

在myDialog.h中:

#pragma once
#include <QDialog>
#include "ui_MyDialog.h"

class myDialogClass : public QDialog {
    Q_OBJECT
public:
    myDialogClass(QWidget *parent = 0) :
        QDialog(parent), ui(new Ui::Dialog) {
        ui->setupUi(this);
    }

    ~myDialogClass() {
        delete ui;
    }

private:
    Ui::Dialog *ui;
};

同样使用Qt Designer,我只用OK和Cancel按钮构建了一个myDialog.ui。

错误出现在指示的位置。在myDialogClass的构造函数中设置断点表明永远不会到达第一行ui-> setupUi(this);失败发生在此之前。

请注意,使用/ MDd选项构建并使用Qt dll的此代码运行正常。将MyDLL构建为静态库并链接它也可以正常运行(直接调用Create()而不是先解析它)。它只是在使用Qt的静态构建来构建MyDLL作为dll而遇到问题。

这是可以做到的吗?如果是这样,我哪里错了?

我尝试过的东西不起作用或者不构建:包括myDialog.h中的Q_IMPORT_PLUGIN宏;试图在dll中构建一个新的QApplication;在发布/ MT中构建发布库。

我没有尝试过的事情:在主app和MyDLL之间混合使用Qt版本的静态和共享版本;混合Qt的静态和共享版本以及运行时库。我真的不感兴趣:关键是要有一个不依赖于Qt或运行时dll的应用程序。

0 个答案:

没有答案