一、描述

QLibrary 对象的实例对单个共享对象文件(库文件)进行操作。QLibrary 以独立于平台的方式提供对库中功能的访问。可以在构造函数中传递文件名,也可以使用 setFileName() 显式设置它。加载库时,除非文件名具有绝对路径,否则QLibrary 将搜索所有系统特定的库位置(例如 Unix 上的 LD_LIBRARY_PATH)。

如果文件名是绝对路径,则首先尝试加载此路径。如果找不到文件,QLibrary 会尝试使用不同平台特定的文件前缀(如 Unix 和 Mac 上的“lib”)和后缀(如 Unix 上的“.so”、Mac 上的“.dylib”或“.dylib”、在 Windows 上的“.dll”)。

如果文件名不是绝对路径,那么 QLibrary 会修改搜索顺序以首先尝试系统特定的前缀和后缀,然后是指定的文件路径。这使得指定仅由其基本名称(即没有后缀)标识的共享库成为可能,因此相同的代码可以在不同的操作系统上运行,但仍然可以最大限度地减少尝试查找库的次数。

因为 QLibrary 会自动查找具有适当后缀的文件,所以建议在文件名中省略文件的后缀。

QLibrary 的多个实例可用于访问同一个物理库。加载后,库将保留在内存中,直到应用程序终止。

解析库中的导出符号

QLibrary 的典型用途是解析库中的导出符号,并调用该符号表示的 C 函数。这被称为“显式链接”,与“隐式链接”相反,当将可执行文件链接到库时,这是由构建过程中的链接步骤完成的。

以下代码片段加载一个库,解析符号“mysymbol”,并在成功时调用该函数。如果出现问题,例如库文件不存在或符号未定义,函数指针将为 nullptr 且不会被调用。

QLibrary myLib("mylib");
typedef void (*MyPrototype)();
MyPrototype myFunction = (MyPrototype) myLib.resolve("mysymbol");
if (myFunction)myFunction();

符号必须从库中导出为 C 函数,resolve() 才能工作。 这意味着如果库是使用 C++ 编译器编译的,则该函数必须包含在 extern "C" 块中。 在 Windows 上,这也需要使用 dllexport 宏。 为方便起见,如果只想调用库中的函数而不先显式加载库,则可以使用静态 resolve() 函数:

typedef void (*MyPrototype)();
MyPrototype myFunction = (MyPrototype) QLibrary::resolve("mylib", "mysymbol");
if (myFunction)myFunction();

二、类型成员

1、enum QLibrary::LoadHint:此枚举描述了可用于更改库加载(load())时处理方式的可能标志。这些值指示加载库时如何解析符号。默认情况下,这些标志都没有设置,并且不会导出外部符号以在其他动态加载的库中解析。在库加载后设置标志无效,并且 loadHints() 不会反映标志更改。

  • ResolveAllSymbolsHint:库中的所有符号在加载时被解析,而不仅仅是在调用 resolve() 时。
  • ExportExternalSymbolsHint:导出库中未解析的和外部符号,以便它们可以在稍后加载的其他动态加载的库中解析。
  • LoadArchiveMemberHint:库的文件名指定存档文件中的特定目标文件。如果设置此标志,则文件名由两个部分组成:路径是对存档文件的引用,后跟是对存档成员的引用的第二个部分。例如,文件名 libGL.a(shr_64.o) 将引用名为 libGL.a 的存档文件中的库 shr_64.o。 这仅在 AIX 平台上受支持。
  • PreventUnloadHint:阻止库从地址空间通过close()卸载。如果之后再有open()调用,库中的静态变量不会重新初始化。
  • DeepBindHint:链接器在解析加载库中的外部符号时优先选择加载库中的定义而不是加载应用程序中的导出定义。此选项仅在 Linux 上受支持。

三、成员函数

1、QLibrary(const QString &fileName, const QString &version, QObject *parent = nullptr)

将加载由 fileName 和完整版本号 version 指定的库。版本号在 Windows 上被忽略。

2、QLibrary(const QString &fileName, int verNum, QObject *parent = nullptr)

将加载由 fileName 和主要版本号 verNum 指定的库。版本号在 Windows 上被忽略。

3、QLibrary(const QString &fileName, QObject *parent = nullptr)

将加载由 fileName 指定的库。

4、~QLibrary()

销毁 QLibrary 对象。除非显式调用 unload(),否则库将保留在内存中,直到应用程序终止。

5、QString errorString()

返回一个文本字符串,其中包含对发生的最后一个错误的描述。当前,仅当 load()、unload() 或 resolve() 由于某种原因失败时才会设置 errorString。

6、【静态】bool isLibrary(const QString &fileName)

fileName 是否具有可加载库的有效后缀。

  • Windows:*.dll、*.DLL
  • Unix/Linux:*.so
  • AIX:*.a
  • HP-UX:*.sl、 *.so (HP-UXi)
  • macOS、iOS:*.dylib、*.bundle、*.so

Unix 上的尾随版本号将被忽略。

7、bool isLoaded()

库是否已加载。

8、bool load()

加载库,如果库加载成功则返回true;否则返回false。由于 resolve() 总是在解析任何符号之前调用此函数,因此没有必要显式调用它。

9、QFunctionPointer resolve(const char *symbol)

【静态】QFunctionPointer resolve(const QString &fileName, const char *symbol)

【静态】QFunctionPointer resolve(const QString &fileName, int verNum, const char *symbol)

【静态】QFunctionPointer resolve(const QString &fileName, const QString &version, const char *symbol)

返回导出的符号符号的地址。如有必要,将加载库。 如果无法解析符号或无法加载库,则该函数返回 nullptr。

QFunctionPointer 是 void (*)() 的 typedef,指向不带参数并返回 void 的函数的指针。

例:

添加一个库工程。内容如下:

testlibrary.h

#ifndef TESTLIBRARY_H
#define TESTLIBRARY_Hextern "C" __declspec(dllexport) int sum(int a, int b);#endif

testlibrary.cpp(必须有cpp文件)

#include "testlibrary.h"int sum(int a, int b)
{return a+b;
}

创建一个工程导出整个库中的函数:

using Fun = int (*)(int, int);int main(int argc, char *argv[])
{QLibrary lib("testLibrary");
//  Fun fun = reinterpret_cast<Fun>(QLibrary::resolve("testLibrary","sum"));Fun fun = reinterpret_cast<Fun>(lib.resolve("sum"));if (fun){qDebug()<<fun(100,200);}else{qDebug()<<lib.errorString();}
}

知识点:类型转换 、函数指针

10、void setFileNameAndVersion(const QString &fileName, int versionNumber)

将 fileName 属性和主要版本号分别设置为 fileName 和 versionNumber。在 Windows 上忽略 versionNumber。

void setFileNameAndVersion(const QString &fileName, const QString &version)

将 fileName 属性和完整版本号分别设置为 fileName 和 version。在 Windows 上忽略version 。

11、bool unload()

如果可以卸载库,则卸载库并返回 true;否则返回false。

这在应用程序终止时自动发生,因此通常不需要调用此函数。

如果 QLibrary 的其他实例正在使用相同的库,则调用将失败,并且只有在每个实例都调用了 unload() 时才会发生卸载。

注意,在 Mac OS X 10.3 (Panther) 上,无法卸载动态库。

Qt插件:QLibrary相关推荐

  1. Qt 插件学习(一)

    插件是什么 注意:这儿暂时不考虑静态插件(潜意识中总觉得它根本就不算插件). 插件是一个动态库(共享库).动态库是一个独立的文件中的独立模块,可被多个程序访问. 先看动态库的两种用法 1. 程序链接时 ...

  2. Qt插件:QPluginLoader

    一.描述 QPluginLoader 提供对 Qt 插件的访问.Qt 插件存储在共享库(DLL)中,与使用 QLibrary 访问共享库相比,它具有以下优势: QPluginLoader 检查插件是否 ...

  3. 构建自己的 Qt 插件系统

    简述 Qt 本身提供了插件相关的技术,但并没有提供一个通用的插件框架!倘若要开发一个较大的 GUI 应用程序,并希望使其可扩展,那么拥有这样一个插件框架无疑会带来很大的好处. 根据 深入理解插件系统  ...

  4. vs2010 Qt插件报错Couldn't register all Qt4VSAddin command解决方案

    打开vs2010,也不存在qt插件: 1.更新你的VS2010到sp1: 2.cmd执行以下命令:(是一个命令,注意32位或者64位路经可能不同确认2个路径的文件存在再执行,否则安装sdk.) win ...

  5. qt插件元数据不包含一个有效的元数据_Qt5个人软件插件使用(低级API)

    前言 今天想看一些Qt 插件系统.看了之后发现Qt支持两种插件方式:高级 API 和低级 API. 高级 API 指的的为Qt软件本身定制插件: 低级 API 指的是为自己写的软件定制插件. 这篇文章 ...

  6. qt插件元数据不包含一个有效的元数据_qt creator源码全方面分析(2-10-2)

    Creating Your First Plugin 本节介绍,如何使用Qt Creator提供的插件模板,来创建Qt Creator插件,并获取对插件的组成和结构的第一印象. 创建一个插件项目 Qt ...

  7. Qt文档阅读笔记-Qt插件DECLARE_INTERFACE METADATA INTERFACES官方解析及实例

    目录 官方解析 Q_DECLARE_INTERFACE Q_PLUGIN_METADATA Q_INTERFACES 博主栗子 官方解析 Q_DECLARE_INTERFACE 此宏用于把标识符与类名 ...

  8. 第九章 国际化、帮助系统和Qt插件

    国际化 就是说该应用程序可以让其他国家的用户使用 1)使用Qt Linguist翻译应用程序 运行lupdate工具,提取翻译文本,生成.ts文件 在Qt Linguist中打开.ts文件,完成翻译工 ...

  9. Qt插件机制介绍及实现

    Qt插件机制介绍及实现 创建应用程序主窗口 创建Qt项目 编辑项目文件ImageView.pro mainwindow.cpp main.cpp mainwindow.cpp 编译运行 插件接口 实现 ...

  10. vs2015安装Qt插件问题

    当在安装好VS2015时,新建Qt工程是吧,可能是Qt插件安装失败,可以关掉VS2015,然后以管理员运行VS2015,重新安装Qt插件就可以了, 当安装好插件之后,创建Qt项目后,编译失败,报Moc ...

最新文章

  1. layui中从上一个js模块中取参数_layui的引用js踩坑
  2. 谈新公司的人才队伍建设
  3. 万众期待的kintone开发账号免费开放申请啦!
  4. 5.解决UltraEdit在无网线情况下连接不到虚拟机上的问题,回环网卡设置
  5. hibernate中的一级缓存
  6. Pytorch 词嵌入word_embedding1初识
  7. php红色字体颜色,php生成文字颜色渐变 高级用法
  8. 表格下拉_【职场充电】要说制作一个漂亮的表格,高手都爱WPS
  9. yum 安装nginx
  10. PHP开源AJAX框架
  11. Android 系统(146)----Android进程保活招数概览
  12. win10 如何卸载OfficeScan
  13. BlueCoat被私募股权公司收购
  14. not all arguments converted during string formatting
  15. linux系统文件夹(转)
  16. HTML5期末大作业:旅游网站设计——中国风的旅游网站(9页) HTML+CSS+JavaScript 学生DW网页设计作业成品 web课程设计网页规划与设计 计算机毕设网页设计源码...
  17. cad移动时捕捉不到基点_CAD很难学吗?其实不然,掌握这10个知识你就能走天下!...
  18. 麒麟合盛(APUS)李涛:APUS云重新定义“云联邦”
  19. Intent 和 Intentfilter
  20. Android Scroller

热门文章

  1. 实验4 LTI系统的时域分析
  2. MeterSphere在开源压测工具JMeter上的分布式优化和实践
  3. 论文笔记 -- Learning Representations for Time Series Clustering
  4. segmentation fault (SIGSEGV) 定位方法
  5. JavaScript中的语句结束符';'
  6. 高通开发系列 - System之分区调整增删快速格式化和挂载等
  7. Golang中的fmt用法
  8. ubuntu 12.04 中使用经典的 GNOME桌面
  9. Non-terminating decimal expansion; no exact representable decimal result异常
  10. android 接入阿里百川,Android Studio集成阿里百川即时通讯,编译异常