在Qt中使用信号会破坏DLL

时间:2016-02-28 14:07:43

标签: c++ qt dll qt5 qt-creator

我在Visual Studio 2013中运行了一个模拟程序,我想要一个简单的GUI来输出/输入数据。

因为我知道一些Qt我决定在Qt Creator中编写一个小的Qt5程序,将它构建为.dll并在我的程序中链接这个.dll。然后程序调用初始化函数来启动GUI。

总的来说这很有效。 GUI就像独立的Qt程序一样工作。但是,一旦我向我的Qt .dll添加了一个自定义信号,就像这样:

//File.h
class MainGui : public QMainWindow
{
    Q_OBJECT

public:

    explicit MainGui(QWidget *parent = 0);
    ~MainGui();

signals:
    void addItemSignal(QGraphicsView* it);

private slots:
    void addItemImpl(QGraphicsView* it);

private:
    Ui::MainGui *ui;
};

//File.cpp
void MainGui::addItemImpl(QGraphicsView *it)
{
    //do anything
}

MainGui::MainGui(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainGui)
{
    QObject::connect(this, &MainGui::addItemSignal,
                     this, &MainGui::addItemImpl);
}

MainGui::~MainGui()
{
    delete ui;
}

我在尝试启动主程序时收到以下错误消息:

The procedure entry point  could not be located in the dynamic link library e:\...\...\MyQtLibrary.dll.

"点"之间的两个空格和"可能"这不是一个错误 - 似乎,由于某种原因,入口点根本没有设置。

经过一些测试后,我发现问题在于在信号中使用Qt类。以下工作正常:

//File.h
class MainGui : public QMainWindow
{
    Q_OBJECT

public:

    explicit MainGui(QWidget *parent = 0);
    ~MainGui();

signals:
    void addItemSignal(void* it);

private slots:
    void addItemImpl(void* it);

private:
    Ui::MainGui *ui;
};

//File.cpp
void MainGui::addItemImpl(void*it)
{
    //do anything
}

MainGui::MainGui(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainGui)
{
    QObject::connect(this, &MainGui::addItemSignal,
                     this, &MainGui::addItemImpl);
}

MainGui::~MainGui()
{
    delete ui;
}

这不仅影响自定义信号,也影响内置信号:

QObject::connect(models, &QStandardItemModel::dataChanged,[this](a b, x y){
        //do something
    });

这也打破了.dll。

我还注意到我必须在Qt Creator中完全重建.dll才能解决问题。删除任何有问题的信号,只是建立没有解决问题。

只有在调试配置中构建Qt .dll时才会发生错误。发布配置运行良好。 MSVC程序是Debug还是Release似乎没有任何效果。我没有改变这些配置的任何默认设置(除了一些与它无关的事情之外)。

我在Qt Creator中在两种配置中发现的唯一区别是调用qmake:

qmake.exe "D:\Dev\Qt Workspace\ArduGui\ArduGui.pro" -r -spec win32-msvc2013 "CONFIG+=debug" "CONFIG+=qml_debug"

这是对Debug配置的调用。在Release中,缺少两个调试配置标志。但是当我弄乱qmake参数时,结果并没有改变。无论是否存在CONFIG+=debugCONFIG+=qml_debug,调试配置始终会导致入口点错误。同样,即使添加了两个标志,Release也会一直有效。

所以在这一点上我跑到了墙上。有没有人有这方面的经验或建议如何调试问题?

更多信息:

我使用Windows 10,MSVC 2013和Qt Creator 3.6和Qt 5.5.1。 .exe和.dll都是通过各自的IDE使用MSVC ++ 12.0编译器编译的。

1 个答案:

答案 0 :(得分:0)

如果它与void*一起工作正常,但不能作为参数传递的QT类指针,我想你没有注册该类能够在信号/插槽机制中使用它:

qRegisterMetaType<QGraphicsView *>("QGraphicsView*");

请务必在首次使用此信号之前调用此功能。 虽然我不确定这是你所有问题的原因。