QT 动态库的使用
在Linux系統中動態庫后綴名為.so; 在Windows系統中動態庫后綴名為.dll
我們在進行模塊化設計開發過程中,往往會將一組功能,封裝成一個動態庫,從哪兒在整個軟件開發升級改特定功能時,只需要修改該動態庫,修改完成后替換該動態庫即可;
這里提到動態庫,它的優缺點如下:
優點
1、可實現不同進程間的資源共享;
2、動態庫升級簡單,只需要替換庫文件,無需重新編譯應用程序;
3、模塊化耦合性小,大規模軟件開發過程中相互獨立;
4、可以控制動態庫的加載跟卸載;
缺點
1、速度相對靜態庫要慢;
2、打包的時候需要連同動態庫一起打包
動態庫的使用方式可分為兩種
一、動態庫的隱式調用
(動態庫新建省略)
1、在指定工程中右鍵添加庫
????????
?
?
?
2、使用庫文件
?
?二、顯示調用動態庫
1、構建庫函數
UnderLayerBehavior_global.h #ifndef UNDERLAYERBEHAVIOR_GLOBAL_H #define UNDERLAYERBEHAVIOR_GLOBAL_H#include <QtCore/qglobal.h>#if defined(UNDERLAYERBEHAVIOR_LIBRARY) # define UNDERLAYERBEHAVIOR_EXPORT Q_DECL_EXPORT #else # define UNDERLAYERBEHAVIOR_EXPORT Q_DECL_IMPORT #endif#endif // UNDERLAYERBEHAVIOR_GLOBAL_H underlayerbehavior.h #ifndef UNDERLAYERBEHAVIOR_H #define UNDERLAYERBEHAVIOR_H#include "UnderLayerBehavior_global.h" #include <QObject>class UNDERLAYERBEHAVIOR_EXPORT UnderLayerBehavior:public QObject {Q_OBJECT public:UnderLayerBehavior(QObject* parent = nullptr);~UnderLayerBehavior();void setDataModel(int id); };//此處初始化插件,顯示調用此處必須添加調用接口 extern "C"{UNDERLAYERBEHAVIOR_EXPORT QObject* getObjPtr();UNDERLAYERBEHAVIOR_EXPORT int pVerify(int);UNDERLAYERBEHAVIOR_EXPORT void setDataModule(int model); }#endif // UNDERLAYERBEHAVIOR_H underlayerbehavior.cpp #include "underlayerbehavior.h"//插件接口變量 UnderLayerBehavior Qunder;UnderLayerBehavior::UnderLayerBehavior(QObject *parent):QObject(parent) { }UnderLayerBehavior::~UnderLayerBehavior(){}void UnderLayerBehavior::setDataModel(int id) {}UNDERLAYERBEHAVIOR_EXPORT QObject* getObjPtr() {return (QObject*)(&Qunder); }//驗證dll UNDERLAYERBEHAVIOR_EXPORT int pVerify(int a) {return a; }UNDERLAYERBEHAVIOR_EXPORT void setDataModule(int model) {Qunder.setDataModel(model); }2、使用該動態庫接口
behaviormanager.h #ifndef BEHAVIORMANAGER_H #define BEHAVIORMANAGER_H#include "BehaviorManager_global.h" #include <QObject> #include <QLibrary> #include <QMap>class BEHAVIORMANAGER_EXPORT BehaviorManager:public QObject {Q_OBJECT public:BehaviorManager(QObject* parent = nullptr);~BehaviorManager();//注冊加載所有DLLbool registerAllLibrary();//卸載所有Dllbool unInstallAllLibaray();//初始化void initModel(); private://獲取指定目錄下的所有DLL文件名QStringList findAllDll(QString path);QMap<QString, QLibrary*> behaviorLibMap; };#endif // BEHAVIORMANAGER_Hbehaviormanager.cpp
#include "behaviormanager.h"#include <QCoreApplication> #include <QDir> #include <QFileInfo>//校驗dll typedef int (*func_verify)(int);//獲取庫函數對象 typedef QObject* (*func_dllObj)();BehaviorManager::BehaviorManager(QObject *parent):QObject(parent) {}BehaviorManager::~BehaviorManager(){}//注冊加載所有DLL bool BehaviorManager::registerAllLibrary() {//獲取可執行文件所在文件夾路徑QString appPath = QCoreApplication::applicationDirPath();QStringList dllNameLst = findAllDll(appPath+"Behavior");for(QString dllName:dllNameLst){QLibrary* curLibrary = new QLibrary("Behavior"+dllName);if(curLibrary->load()){//校驗庫文件func_verify pfuncVerify = (func_verify)(curLibrary->resolve("pVerify"));//調用庫的接口if(0 != pfuncVerify(0)){delete curLibrary;curLibrary = nullptr;continue;}behaviorLibMap.insert(dllName, curLibrary);//dll加載成功}else{//dll 加載失敗}}if(0 == behaviorLibMap.size()){return false;}return true; }//卸載所有Dll bool BehaviorManager::unInstallAllLibaray() {for(QLibrary* pLibrary:behaviorLibMap.values()){if(pLibrary->isLoaded()){//libray被加載pLibrary->unload();//卸載}} }//使用庫函數定義對象 void BehaviorManager::initModel() {auto itor = behaviorLibMap.begin();while (itor != behaviorLibMap.end()) {QLibrary* pLibrary = itor.value();func_dllObj pDllObj = (func_dllObj)(pLibrary->resolve("getObjPtr"));QObject* Obj = pDllObj();if(nullptr == Obj){//判斷對象是否為空}} }//獲取指定目錄下的所有DLL文件名 QStringList BehaviorManager::findAllDll(QString path) {QStringList dllNameLst;QDir fDir(path);//設置文件過濾fDir.setFilter(QDir::Files);QFileInfoList fileLst = fDir.entryInfoList();for(int i=0; i<fileLst.size();i++){//獲取后綴名QString filetype = fileLst.at(i).suffix();//對比后綴名 dll 忽略大小寫if(0 == filetype.compare("dll", Qt::CaseInsensitive)){dllNameLst.append(fileLst.at(i).baseName());}}return dllNameLst; }這里就是動態庫的基本用法!
總結
- 上一篇: linux安装cppcheck
- 下一篇: 东京大学工学系研究科数学套路总结系列之一