QT 动态库的使用
在Linux系统中动态库后缀名为.so; 在Windows系统中动态库后缀名为.dll我们在进行模块化设计开发过程中,往往会将一组功能,封装成一个动态库,从哪儿在整个软件开发升级改特定功能时,只需要修改该动态库,修改完成后替换该动态库即可;这里提到动态库,它的优缺点如下:优点1、可实现不同进程间的资源共享;2、动态库升级简单,只需要替换库文件,无需重新编译应用程序;3、模块化耦合性小,大规模软件开
·
在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();
//注册加载所有DLL
bool registerAllLibrary();
//卸载所有Dll
bool unInstallAllLibaray();
//初始化
void initModel();
private:
//获取指定目录下的所有DLL文件名
QStringList findAllDll(QString path);
QMap<QString, QLibrary*> behaviorLibMap;
};
#endif // BEHAVIORMANAGER_H
behaviormanager.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;
}
这里就是动态库的基本用法!
更多推荐
已为社区贡献1条内容
所有评论(0)