Qt 可以调用 dll, 插件可以dll形式存在。但是插件的话,要有个 interface 将 app 和 plugin 耦合起来。(此处说 dll 是特指在 Win 平台下)
应用场景:将类、函数封装成dll,供调用。
主要参考: https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application
一、显式调用
需要指定头文件 .h 和 库文件 .lib 的位置,即可编译。
指定可以手写,也可以用向导添加
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/./ -ltest else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/./ -ltestd INCLUDEPATH += $$PWD/. DEPENDPATH += $$PWD/.
二、隐式调用
使用 QLibrary 加载 动态库文件。 *.h 和 *.lib 不需要。
QLibrary library("qlibraryLibrary.dll"); if (!library.load()) qDebug() << library.errorString(); if (library.load()) qDebug() << "library loaded"; typedef QWidget *(*CreateWidgetFunction)(); CreateWidgetFunction cwf = (CreateWidgetFunction) library.resolve("createWidget1"); if (cwf) { QWidget *widget = cwf(); if (widget) widget->show(); } else { qDebug() << "Could not show widget from the loaded library"; }
对于一去二三里的例子,代码综合了类和外部函数的使用
#include <QApplication> #include <QLibrary> #include <QDebug> #include "sharedlibrary.h" #include <QMessageBox> int main(int argc, char *argv[]) { QApplication a(argc, argv); QLibrary mylib("SharedLibrary.dll"); if (mylib.load()) { qDebug() << "library loaded"; //!class typedef SharedLibrary* (*GetSharedLibrary)();//定义函数指针,获取类TestDLL对象; 需要头文件 sharedlibrary.h GetSharedLibrary getSharedLibrary = reinterpret_cast<GetSharedLibrary>(mylib.resolve("getSharedLibrary")); if (getSharedLibrary) { SharedLibrary *pLib = getSharedLibrary(); pLib->updateBackgroud(); pLib->resize(400,200); pLib->subtract(100, 40); pLib->show(); pLib->setWindowTitle("Test ShareLibrary"); }else{ qDebug() << "Could not show widget from the loaded library"; } //! Function typedef int (*Fun)(int, int); //定义函数指针,int add(int a,int b); Fun add = reinterpret_cast<Fun>(mylib.resolve("add")); if (add) { int nResult = add(51, 5); QMessageBox::information(nullptr, "Tip", QString::number(nResult)); }else{ qDebug() << "Could not add from the loaded library"; } }else{ qDebug() << mylib.errorString(); } return a.exec(); }
三、改进
注意到提示旧的转变风格,改为 即可。
C++ 有4种转换
dynamic_cast <new_type> (expression) reinterpret_cast <new_type> (expression) static_cast <new_type> (expression) const_cast <new_type> (expression)
延伸阅读
- QT插件和普通动态库的差别?
https://bbs.csdn.net/topics/390843246?page=1 - Qt之创建并使用共享库
http://blog.sina.com.cn/s/blog_a6fb6cc90102vsdn.html - How to create a library with Qt and use it in an application
https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application - C#和C++ 有关DLL的
https://blog.csdn.net/qq_36196748/article/details/82756551
显式(静态)调用:LIB+DLL+.H ,注意.H中的dllexport改为dllimport
隐式(动态)调用:DLL+函数原型声明,先LoadLibrary,再GetProcAddress(即找到DLL中的函数的地址),不用后FreeLibrary;
使用C++/clr语法,采用正确的访问托管对象,即:使用“^”,而不是用“*” - 用C++调用C#生成的dll(动态链接库文件)
https://blog.csdn.net/qq_36196748/article/details/81218214 - Qt5的插件机制(5)–QLibrary类与QPluginLoader类
https://blog.csdn.net/NewThinker_wei/article/details/41292069