问题描述:
B.dll构建依赖于A.dll,运行的时候B捕捉不到A发出的信号(A内部可以捕捉自己的信号)
问题分析:
猜测:信号无法监听或接收与构建无关,cmake只是构建工具与运行时是没有关系(只跟配置有关,比如:未声明CMAKE_AUTOMOC 的选项为 ON):
1、信号的参数中包含了未注册类型(使用qRegisterMetaType注册)
2、若是异步线程,线程中未使用标准的QEventLoop的事件循环对象。
3、连接了非slots定义的成员函数。
一一验证都不是。
两个都shared类型的动态链接库,未使用dllexport 导出。因此B无法解析A中信号的地址
解决办法:
引入Q_DECL_EXPORT与Q_DECL_IMPORT,在dll构建类需要引入其他动态库类,函数时,这些类和函数前等需要导出Q_DECL_EXPORT,此被构建的dll类前需要声明为Q_DECL_IMPORT
拓展:(visual studio帮助文档给出了详细解释使用 __declspec(dllimport) 导入函数调用 | Microsoft Learn)
虽然在函数声明中使用 __declspec(dllimport)
是可选的,但如果你使用此关键字,编译器会生成更高效的代码。 不过,必须对导入的可执行文件使用 __declspec(dllimport)
,以访问 DLL 的公共数据符号和对象。 请注意,DLL 的用户仍需要与导入库链接。
可以对 DLL 和客户端应用程序使用相同的头文件。 为此,请使用特殊的预处理器符号来指示是生成 DLL 还是生成客户端应用程序。 例如:
#ifdef _EXPORTING
#define CLASS_DECLSPEC __declspec(dllexport)
#else
#define CLASS_DECLSPEC __declspec(dllimport)
#endif
class CLASS_DECLSPEC CExampleA : public CObject
{ ... class definition ... };
这样在需要导出时添加声明_EXPORTING即可,不声明该宏则为导入
CMAKE预编译添加声明方法:
target_compile_definitions(QToolUi PRIVATE UI_TOOL_LIBRARY=1)