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

使用QT5创建动态库以及如何在程序运行时加载动态库

本文介绍了如何使用QT5创建动态库,以及如何在程序运行时加载动态库。这种方式类似于Qt的应用程序插件机制,插件的方式可以直接获取动态库中类的实例,而此方式只能到函数级,从库中获取函数的地址并转换为对应的函数指针来执行。
下面以实例进行介绍:

创建动态库

  1. 新建库项目,pro文件如下:
QT += widgets
TEMPLATE = lib		#输出为动态库
CONFIG += c++11
DEFINES += QT_DEPRECATED_WARNINGS
TARGET= mplugin
SOURCES += \
    mplugin.cpp
HEADERS += \
    mplugin.h
  1. 将cpp中需要导出的函数用extern “C”
#ifndef MPLUGIN_H
#define MPLUGIN_H

#include <QObject>

/* QT在windows下导出符号必须要用“__declspec(dllexport)”修饰,否则QLibrary会加载失败 */
#ifdef Q_OS_WIN		
#define MY_EXPORT __declspec(dllexport)
#else
#define MY_EXPORT
#endif

class Mplugin
{
public:
    Mplugin();
    void show(QString s);
};

#endif // MPLUGIN_H

#include "mplugin.h"
#include <QMessageBox>
#include <QWidget>
Mplugin::Mplugin()
{
}
//调用此函数显示一个消息框
void Mplugin::show(QString s)
{
    QWidget w;
    QMessageBox::warning(&w,"warning!",s);
}
extern "C" MY_EXPORT void myShow(QString s)
{
    Mplugin plu;
    plu.show(s);
}

使用动态库

新建另一项目,源码如下:

#include <QApplication>
#include <QLibrary>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    /* 加载库文件,可以使用绝对路径或相对路径,mplugind.dll为上面动态库项目编译产生的二进制库文件 */
    QLibrary lib("D:/Documents/build-mmplugin-Desktop_x86_windows_msvc2019_pe_64bit-Debug/mplugin/debug/mplugind.dll");
    typedef void (*FUN)(QString);		//此格式同导出符号的格式

	/* 解析动态库中的符号,如果不存在会返回NULL */
    FUN fun = (FUN)lib.resolve("myShow");
    if (fun) {
        fun("test"); //运行到此处会显示消息框
    }
    return a.exec();
}

注意事项

  1. 编写为动态库的代码中,所有需要外部调用的函数必须为C函数,Cpp中需要使用extern "C"导出。
  2. windwos下导出的符号需要使用extern “C” __declspec(dllexport)**来修饰。可以在头文件中加入如下的代码段,然后在源代码文件中所有需要导出的CPP函数加上extern “C” MY_EXPORT即可实现不修改代码就可以在不同的系统下使用。
  #ifdef Q_OS_WIN
  #define MY_EXPORT __declspec(dllexport)
  #else
  #define MY_EXPORT
  #endif

相关文章:

  • 装修经验分享
  • linux下socket常见问题整理
  • 奇偶校验的原理
  • CRC循环冗余校验原理
  • ceph基本环境搭建 使用cephadm
  • ceph-deploy常见问题处理
  • 解决linux下程序运行时无法找到动态库的问题error while loading shared libraries
  • Qt样式表的使用setStyleSheet
  • Qt实现关闭主/父窗口后同时关闭其他窗口的方法事件过滤器(eventFilter)的使用
  • StartUML4.0.1的使用方法
  • 结构型模式--Proxy代理模式
  • C++的Lambda表达式的用法
  • 微信小程序学习之rich-text的嵌入静态HTML
  • 微信小程序CSS Flexbox(弹性盒子)布局模块
  • 语义化版本 2.0.0 -- 如何使用软件版本号
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • 2019.2.20 c++ 知识梳理
  • Angular 响应式表单之下拉框
  • Angular6错误 Service: No provider for Renderer2
  • Apache Pulsar 2.1 重磅发布
  • HTTP传输编码增加了传输量,只为解决这一个问题 | 实用 HTTP
  • Linux Process Manage
  • MySQL数据库运维之数据恢复
  • mysql中InnoDB引擎中页的概念
  • React-Native - 收藏集 - 掘金
  • spring boot 整合mybatis 无法输出sql的问题
  • Sublime Text 2/3 绑定Eclipse快捷键
  • Vue实战(四)登录/注册页的实现
  • vue数据传递--我有特殊的实现技巧
  • Webpack 4x 之路 ( 四 )
  • 搞机器学习要哪些技能
  • 技术攻略】php设计模式(一):简介及创建型模式
  • 聊一聊前端的监控
  • 区块链共识机制优缺点对比都是什么
  • 容器化应用: 在阿里云搭建多节点 Openshift 集群
  • 使用SAX解析XML
  • 数据科学 第 3 章 11 字符串处理
  • 探索 JS 中的模块化
  • #单片机(TB6600驱动42步进电机)
  • (+4)2.2UML建模图
  • (3)选择元素——(17)练习(Exercises)
  • (Pytorch框架)神经网络输出维度调试,做出我们自己的网络来!!(详细教程~)
  • (vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (含react-draggable库以及相关BUG如何解决)固定在左上方某盒子内(如按钮)添加可拖动功能,使用react hook语法实现
  • (免费领源码)python+django+mysql线上兼职平台系统83320-计算机毕业设计项目选题推荐
  • (十八)三元表达式和列表解析
  • (原創) 如何將struct塞進vector? (C/C++) (STL)
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • (转)nsfocus-绿盟科技笔试题目
  • .NET Micro Framework 4.2 beta 源码探析
  • .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况
  • .NET使用HttpClient以multipart/form-data形式post上传文件及其相关参数
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(白虎组)