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

QT动态加载动态库 QLibrary

qt中加载动态库有两种方式,一种跟在vs中一样,使用生成的 xxx.dll(linux下是 xxx.so)和xxx.h。第二种方式是使用QLibray动态加载,此种方式只需要dll文件(linux下是so文件)即可。

这里介绍使用QLibray的方式加载动态库:
一、新建一个工程Demo,作为动态库工程。
.pro文件配置如下:

QT       += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgets#生成库
TEMPLATE = lib
#shared 动态库
CONFIG += c++17 shared
#生成目录
DESTDIR = $$PWD/binunix{
#linux下生成无版本号链接的so文件
CONFIG+=plugin
}
#导出宏标识
DEFINES += DEMOLL_LIBRARY# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0SOURCES += \demo.cpp \main.cpp \mainwindow.cppHEADERS += \demo.h \interface.h \mainwindow.h# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

1.创建接口文件,供库工程和测试工程使用

//interface.h
#ifndef INTERFACE_H
#define INTERFACE_Hclass Interface
{
public:Interface(){}virtual ~Interface(){}virtual void add(int x,int y)=0;
};#endif // INTERFACE_H

2.创建要导出的类 Demo,并继承Interface
除了导出Demo类外,还可以添加全局函数:g_print()

#ifndef DEMO_H
#define DEMO_H
#include <QObject>
#include "interface.h"//DEMOLL_LIBRARY 宏已经在pro文件中定义,所以是导出类/函数
#if defined(DEMOLL_LIBRARY)
# define MYAPI Q_DECL_EXPORT
#else
# define MYAPI Q_DECL_IMPORT
#endifclass MYAPI Demo :public Interface
{
public:Demo();virtual ~Demo();void add(int x,int y)override;
};extern "C"
{//类导出MYAPI Interface* createDemo();MYAPI void destoryDemo(Interface *obj);//全局函数导出MYAPI void g_print(QString str);
}#endif // DEMO_H
#include "demo.h"
#include <QDebug>Demo::Demo()
{
}
Demo::~Demo()
{
}
void Demo::add(int x, int y)
{qDebug()<<x+y;
}//类导出
MYAPI Interface* createDemo()
{return new Demo;
}
MYAPI void destoryDemo(Interface *obj)
{delete obj;
}
//全局函数导出
MYAPI void g_print(QString str)
{qDebug()<<__FUNCTION__<<"@:"<<str;
}

3.构建工程
注意:构建的时候选择MinGW,那么测试工程也要选择MinGW。并且32位或者64位要一一对应。
这里构建好之后,可以在bin目录下找到dll文件(linux下是.so文件),这个就是之后要用到的库文件。
在这里插入图片描述
二、新建一个测试工程test(带不带界面都可以)
1.将生成的dll文件和接口文件(interface.h)拷贝到测试工程.pro目录下,新建一个lib文件夹放进去。
在这里插入图片描述
在这里插入图片描述2.
2.在测试工程的.pro文件配置 动态库目录,和头文件目录

QT       += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += c++17
#生成目录
DESTDIR =$$PWD/bin# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0SOURCES += \main.cpp \mainwindow.cppHEADERS += \mainwindow.hFORMS += \mainwindow.ui#dll目录
win32{
LIBS += -L$$PWD/lib
}unix{
LIBS += -L$$PWD/lib
}
#头文件目录
INCLUDEPATH +=$$PWD/lib
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLibrary>
#include <QDebug>
#define lld qDebug()//引入接口头文件
#include "interface.h"
//函数指针
typedef Interface*(*CreateDemoFunc)();
typedef void(*DestoryDemoFunc)(Interface*);
typedef void(*GprintFunc)(QString str);MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//加载动态库QLibrary lib("testdll");if(!lib.load()){lld<<"加载dll失败";return;}//获取导出的函数指针CreateDemoFunc createDemo = (CreateDemoFunc)lib.resolve("createDemo");//createDemo是demo中要导出的DestoryDemoFunc destoryDemo = (DestoryDemoFunc)lib.resolve("destoryDemo");GprintFunc gPrint = (GprintFunc)lib.resolve("g_print");if(!createDemo||!destoryDemo||!gPrint){lld<<"解析函数失败";return;}//获取导出的类Interface *demo = createDemo();if(!demo){lld<<"创建失败";}demo->add(1,2);//全局函数gPrint("2333");
}

3.运行测试程序,可以在控制台看到输出
在这里插入图片描述
三、如果要在linux下测试,只需要拷贝对应的so文件即可
在这里插入图片描述

http://www.dtcms.com/a/287365.html

相关文章:

  • 从车险理赔到快递签收:打通区块链与现实世界的“最后一公里”——解密预言机(Oracle)
  • aws(学习笔记第四十九课) ECS集中练习(1)
  • 基于深度学习的推荐系统:从协同过滤到神经网络
  • Java机考题:815. 公交路线 图论BFS
  • OpenCV 官翻7 - 对象检测
  • 用户中心——比如:腾讯的QQ账号可以登录到很多应用当中 02
  • Vue 3 中导出 Excel 文件
  • github上传代码
  • window、DOM、document、html 他们之间的关系是什么?
  • springboot基础-demo
  • Java中缓存的使用浅讲
  • Netty集群方案详解与实战(Zookeeper + Redis + RabbitMQ)
  • 深入理解设计模式:策略模式的艺术与实践
  • 云端成本治理利器:亚马逊云科技智能仪表盘(AWS Cost Intelligence Dashboard)深度解析
  • Android14 SystemUI 启动流程(2)
  • Spring MVC @RequestParam注解全解析
  • Spring MVC源码分析 DispatcherServlet#getHandlerAdapter方法
  • C# 中的强大运算符
  • 掌握配置文件(一):精通`properties`与`yml`的语法及选择
  • 【iOS】ZARA仿写
  • MySQL详解二
  • ros2高级篇之高可用启动文件及配置编写
  • 深入解析HDFS写入流程:管道机制与数据可靠性保障
  • (Python)类和类的方法(基础教程介绍)(Python基础教程)
  • 7月19日日记
  • SpringAI_Chat模型_DeepSeek模型--基础对话
  • Word快速文本对齐程序开发经验:从需求分析到实现部署
  • 嵌入式单片机开发 - Keil MDK 复制工程
  • Python day18
  • MySQL事务管理(上)(12)