在 Qt 中使用信号会破坏 DLL
Posted
技术标签:
【中文标题】在 Qt 中使用信号会破坏 DLL【英文标题】:Using signals in Qt breaks DLL 【发布时间】:2016-02-28 14:07:42 【问题描述】:我正在 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.
“point”和“could”之间的两个空格并没有错 - 出于某种原因,入口点似乎根本没有设置任何东西。
经过一些测试,我发现问题在于在信号中使用 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 在 Debug 配置中构建时才会发生该错误。发布配置运行良好。 MSVC 程序是 Debug 还是 Release 似乎都没有效果。我没有更改任何这些配置的任何默认设置(除了一些绝对与它无关的东西)。
我在 Qt Creator 中发现这两种配置的唯一区别是 qmake 的调用:
qmake.exe "D:\Dev\Qt Workspace\ArduGui\ArduGui.pro" -r -spec win32-msvc2013 "CONFIG+=debug" "CONFIG+=qml_debug"
这是对调试配置的调用。在 Release 中,缺少两个调试配置标志。但是当我弄乱 qmake 参数时,结果并没有改变。无论CONFIG+=debug
或CONFIG+=qml_debug
是否存在,调试配置总是会导致入口点错误。同样,即使添加了两个标志,Release 也始终有效。
所以在这一点上,我正在靠墙奔跑。有没有人有这方面的经验或者可以就如何调试问题提出建议?
更多信息:
我正在使用 Windows 10、MSVC 2013 和 Qt Creator 3.6 和 Qt 5.5.1。 .exe 和 .dll 都是通过各自的 IDE 使用 MSVC++ 12.0 编译器编译的。
【问题讨论】:
【参考方案1】:如果它适用于void*
,但不适用于作为参数传递的 QT 类指针,我猜你还没有注册该类以便能够在信号/插槽机制中使用它:
qRegisterMetaType<QGraphicsView *>("QGraphicsView*");
请务必在第一次使用此信号之前调用此函数。 虽然我不确定这是你所有问题的原因。
【讨论】:
QGraphicsView 是一个标准的 Qt 类。据我所知,我只需要以这种方式注册定制课程。 (我也从未在任何其他项目中使用内置类。)以上是关于在 Qt 中使用信号会破坏 DLL的主要内容,如果未能解决你的问题,请参考以下文章
使用 MSYS 复制 System32 DLL 会破坏库的 64 位存在