当前位置: 首页 > article >正文

二十四、Qt之使用动态库

 原创

mb62b19580f1ddc2022-06-21 19:59:16博主文章分类:QT©著作权

文章标签库文件g++动态库文章分类后端开发阅读数635

在 Qt 中,动态库又叫共享库

一、当只有 dll 库 、 头文件时的引入方式

步骤和下面基本一致,唯一的就是配置文件的差异,配置文件如下:

 

#头文件目录
INCLUDEPATH += $$PWD/include
#设置添加的库文件
LIBS += -L$$PWD/include/ -llibqjson-qt5

  • 1.
  • 2.
  • 3.
  • 4.

二、当有 dll库 、 头文件 、 lib库 文件时的引入方式

(一)、调用动态库之方式一:隐式链接调用动态库

备注:应用程序的编译器版本+位数必须与动态库的编译器版本+位数一致,才能编译通过!!比如动态链接库是在 MSVC2015+32bit 环境编译的,那么应用程序的编译环境也必须是 MSVC2015+32bit。

第一步:收集

在项目的源文件目录下创建一个 include 子目录,将库的头文件 qwdialogpen.h 、mysharedlib_global.h、插件的 debug 和 release 两种模式编译生成的库文件 mySharedLibd.lib 和 mySharedLib.lib 复制到此目录下,项目在编译链接时需要此头文件和库文件。

备注:动态库在debug编译时,生成的 lib 文件不会带 d 结尾,需要手动在文件名后加 “d”!生成的 dll 文件暂时不要动,也不要改变命名,等后面复制到可执行文件的目录下。

第二步:导入库文件

方式一:引导方式

右击项目,在弹出的菜单中选择 “添加库…” ,选择库类型时,选择 外部库“External Library”;选择库文件位置时,就把 include 文件夹下的 mySharedLib.lib 选中即可,会自动填充 “Include path”编辑框,选择 windows 平台,连接方式选择 Dynamic(动态链接库,插件是Dynamic) ,勾选下方 Add “d” suffix for debug version,表示在 debug 版本的库名称后面添加一个字母 “d”,以便编译器自动区分 release 和 debug 版本的库文件。

方式二:手动代码导入

修改项目文件 sharedLibUser.pro,添加:

MSVC编译模式:
 

#设置添加的库文件,会判断当前项目时以 debug 还是 release 模式编译
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/include/ -lmySharedLib
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/include/ -lmySharedLib
#头文件目录
INCLUDEPATH += $$PWD/include
#项目依赖目录
DEPENDPATH += $$PWD/include

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

这样只有MSVC编译器可以编译

MinGw 编译模式:
 

win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$PWD/include/libmySharedLib.a
else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$PWD/include/libmySharedLibd.a
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$PWD/include/mySharedLib.lib
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$PWD/include/mySharedLib.lib

  • 1.
  • 2.
  • 3.
  • 4.

这样只有 MinGW编译器可以编译

MSVC + MinGw 两种编译模式:
 

#设置添加的库文件,会判断当前项目时以 debug 还是 release 模式编译
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/include/ -lmySharedLib
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/include/ -lmySharedLib
#头文件目录
INCLUDEPATH += $$PWD/include
#项目依赖目录
DEPENDPATH += $$PWD/include

win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$PWD/include/libmySharedLib.a
else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$PWD/include/libmySharedLibd.a
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$PWD/include/mySharedLib.lib
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$PWD/include/mySharedLib.lib

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

这样 MSVC 和 MinGW编译器都可以编译

第四步:引入头文件,并使用

 

#include "qwdialogpen.h"

  • 1.

第五步:编译项目

编译

在 debug 和 release 两种模式下分别编译。

将两种模式编译生成的 dll 文件分别复制到对应的可执行文件的目录下
 

E:\Qt_Demo\build-shareLibUser-Desktop_Qt_5_9_0_MSVC2015_32bit-Debug\debug
E:\Qt_Demo\build-shareLibUser-Desktop_Qt_5_9_0_MSVC2015_32bit-Release\release

  • 1.
  • 2.

备注:debug 模式下编译生成的 dll 文件名千万不要变动(末位加 “d”),保持原样,否则会报错!!!

第六步:运行项目

(二)、调用动态库之方式二:显式链接调用动态库

显示链接调用共享库是应用程序运行时才加载共享库文件,并调用库里的函数的。应用程序编译时无需共享库的任何文件,只需知道函数名和函数的原型即可。所以,这种方式可以调用其他语言编写的 dll 文件。
显示链接调用共享库是通过 QLibrary 类实现的,在 QLibrary 的构造函数中传递一个文件名,也可以是不带后缀的单独文件名。QLibrary 会根据运行的平台自动查找不同后缀的共享库文件,例如 Unix 上是 “.so”,Mac上是“.dylib”,Windows 上是 “.dll”。
一个动态链接库在内存里只有一个实例,也就是说即使有多处调用了这个动态链接库里的函数,它也只会被载入一次,如果不是所有的实例都调用 unload() 卸载它,那么它会在应用程序退出时才卸载。
案例:
用 Delphi 编写一个 dll 项目,生成一个 DelphiDLL.dll 文件,这个文件里只有一个函数,函数原型为:

 

function triple(N:integer):integer;

  • 1.

它会计算传递参数 N 的3倍值并返回。

 

void MyMainWindow::on_btnTrigger_clicked()
{
//初始化 QLibrary
QLibrary myLib("DelphiDLL");
//判断是否加载入内存
if (myLib.isLoaded())
QMessageBox::information(this, "信息", "DelphiDLL.dll 已经被载入,第1处");
//声明 dll 中函数原型
typedef int (*FunDef)(int);
//解析 dll 中函数
FunDef myTriple = (FunDef) myLib.resolve("triple");
//调用函数
int value = myTriple(ui->spinBoxInput->value());
ui->spinBoxOutput->setValue(value);
//判断是否加载入内存
if (myLib.isLoaded())
QMessageBox::information(this, "信息", "DelphiDLL.dll 已经被载入,第2处");
}

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

在案例中,第一次点击按钮时,只有第2处信息框显示,说明初始化了 QLibrary 之后,动态链接库没有立即被载入内存;第二次单击时,会出现两个信息框,说明动态链接库至上次载入内存中后,一直在内存中。
在案例中,我们即使不将调用的 dll 文件不放入可执行程序中,编译和运行也不会报错,只有点击按钮触发加载时才会报错,所以我们需要将 dll 文件复制到可执行文件夹下!!!


http://www.kler.cn/a/441201.html

相关文章:

  • Linux二进制部署K8s集群的平滑升级教程
  • 后端token校验流程
  • 【安全测试】测开方向学习遇到的问题记录
  • 神经网络和深度学习
  • Maui学习笔记- SQLite简单使用案例02添加详情页
  • Leetcode刷题-不定长滑动窗口
  • 学习笔记070——Java中【泛型】和【枚举】
  • 如何获取抖音item_get_app接口
  • 【Linux】—简单实现一个shell(myshell)
  • 快速掌握源码部署Filebeat
  • 浅谈基于单片机的计步器设计
  • 架构师之路--springboot核心类SpringApplication方法run的源码启动流程
  • 【华为OD机试真题】【2024年E卷】数值同化-队列BFS(C++/Java/Python)
  • 网络安全考题
  • 禁用硬件合成 (Hardware Composer, HWC)
  • ChatGPT搜索全新升级,向全体用户开放,近屿智能助力AI行业发展
  • Linux:入门篇——万字长篇解析
  • 生活小妙招之UE CaptureRT改
  • Qt编译MySQL数据库驱动
  • Linux 各发行版安装 ping 命令指南
  • 解决Windows Server环境下PPTX转PDF时WebP格式图片缺失
  • 程序设计考题汇总(四:SQL练习)
  • Pytorch | 从零构建GoogleNet对CIFAR10进行分类
  • 【Linux课程学习】:第二十一弹---深入理解信号(中断,信号,kill,abort,raise,larm函数)
  • Linux学习笔记思维导图(系统调用+网络编程)
  • 信息安全实训室网络攻防靶场实战核心平台解决方案