QLibrary Class
QLibrary 类可在运行时加载共享库。更多
头文件: | #include <QLibrary> |
CMake: | find_package(Qt6 REQUIRED COMPONENTS Core) target_link_libraries(mytarget PRIVATE Qt6::Core) |
qmake: | QT += core |
继承: | QObject |
- 所有成员(包括继承成员)的列表
- QLibrary 属于Plugin Classes(插件类)。
注意:该类中的所有函数都是可重入的。
公共类型
enum | LoadHint { ResolveAllSymbolsHint, ExportExternalSymbolsHint, LoadArchiveMemberHint, PreventUnloadHint, DeepBindHint } |
flags | LoadHints |
属性
公共函数
QLibrary(QObject *parent = nullptr) | |
QLibrary(const QString &fileName, QObject *parent = nullptr) | |
QLibrary(const QString &fileName, const QString &version, QObject *parent = nullptr) | |
QLibrary(const QString &fileName, int verNum, QObject *parent = nullptr) | |
virtual | ~QLibrary() |
QString | errorString() const |
QString | fileName() const |
bool | isLoaded() const |
bool | load() |
QLibrary::LoadHints | loadHints() const |
QFunctionPointer | resolve(const char *symbol) |
void | setFileName(const QString &fileName) |
void | setFileNameAndVersion(const QString &fileName, const QString &version) |
void | setFileNameAndVersion(const QString &fileName, int versionNumber) |
void | setLoadHints(QLibrary::LoadHints hints) |
bool | unload() |
静态公共成员
bool | isLibrary(const QString &fileName) |
QFunctionPointer | resolve(const QString &fileName, const char *symbol) |
QFunctionPointer | resolve(const QString &fileName, const QString &version, const char *symbol) |
QFunctionPointer | resolve(const QString &fileName, int verNum, const char *symbol) |
详细说明
QLibrary 对象的实例在单个共享对象文件(我们称之为 "库",但也称为 "DLL")上运行。QLibrary 以独立于平台的方式提供对库中功能的访问。您可以在构造函数中传递文件名,也可以使用setFileName() 明确设置文件名。加载库时,QLibrary 会搜索所有系统特定的库位置(如 Unix 上的LD_LIBRARY_PATH
),除非文件名是绝对路径。
如果文件名是绝对路径,则首先尝试加载该路径。如果找不到文件,QLibrary 会尝试使用不同平台特定的文件前缀(如 Unix 和 Mac 上的 "lib")和后缀(如 Unix 上的".so"、Mac 上的".dylib "或 Windows 上的".dll")来加载文件名。
如果文件路径不是绝对路径,QLibrary 会修改搜索顺序,先尝试系统特定的前缀和后缀,然后再尝试指定的文件路径。
这样就可以指定只用基名(即不带后缀)标识的共享库,因此相同的代码可以在不同的操作系统上运行,但仍能最大限度地减少查找库的尝试次数。
最重要的函数是load() 用来动态加载库文件,isLoaded() 用来检查加载是否成功,resolve() 用来解析库中的符号。如果库尚未加载,则resolve() 函数会隐式尝试加载库。多个 QLibrary 实例可用于访问同一个物理库。一旦加载,库将一直保留在内存中,直到应用程序终止。您可以尝试使用unload() 来卸载一个库,但如果其他 QLibrary 实例也在使用同一个库,调用就会失败,只有当每个实例都调用了unload() 后,卸载才会发生。
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() 。为方便起见,如果只想调用库中的函数,而不想先明确加载库,可以使用静态resolve() 函数:
typedef void (*MyPrototype)(); MyPrototype myFunction = (MyPrototype) QLibrary::resolve("mylib", "mysymbol"); if (myFunction) myFunction();
另请参见 QPluginLoader 。
成员类型文档
枚举 QLibrary::LoadHint
flags QLibrary::LoadHints
此枚举描述了在加载库时可用于改变库处理方式的可能提示。这些值表示加载库时如何解析符号,可使用setLoadHints() 函数指定。
常量 | 值 | 说明 |
---|---|---|
QLibrary::ResolveAllSymbolsHint | 0x01 | 导致在加载库时解析库中的所有符号,而不仅仅是在调用resolve() 时。 |
QLibrary::ExportExternalSymbolsHint | 0x02 | 导出库中未解析的外部符号,以便在以后加载的其他动态加载库中解析这些符号。 |
QLibrary::LoadArchiveMemberHint | 0x04 | 允许用库文件名指定归档文件中的特定对象文件。如果给出此提示,库的文件名将由一个路径(即对归档文件的引用)和一个对归档文件成员的引用组成。 |
QLibrary::PreventUnloadHint | 0x08 | 在调用 close() 时,防止从地址空间卸载库。如果以后调用 open() 函数,库的静态变量不会被重新初始化。 |
QLibrary::DeepBindHint | 0x10 | 指示链接器在解析已加载库中的外部符号时,优先选择已加载库中的定义,而不是加载应用程序中的导出定义。此选项仅在 Linux 下支持。 |
LoadHints 类型是QFlags<LoadHint> 的类型定义。它存储 LoadHint 值的 OR 组合。
另请参阅 loadHints 。
属性文档
fileName : QString
该属性包含库的文件名
我们建议在文件名中省略文件的后缀,因为QLibrary 会自动查找具有相应后缀的文件(参见isLibrary() )。
加载程序库时,QLibrary 会搜索所有系统特定的程序库位置(例如,Unix 上的LD_LIBRARY_PATH
),除非文件名有绝对路径。成功加载程序库后,fileName() 将返回程序库的全限定文件名,如果在构造函数中给出或传递给 setFileName(),则包括程序库的完整路径。
例如,在 Unix 平台上成功加载 "GL "库后,fileName() 将返回 "libGL.so"。如果最初传递的文件名是"/usr/lib/libGL",则 fileName() 将返回"/usr/lib/libGL.so"。
访问函数:
QString | fileName() const |
void | setFileName(const QString &fileName) |
loadHints : LoadHints
给load() 函数一些提示,告诉它应该如何运行。
您可以就如何解析符号给出一些提示。通常情况下,符号不会在加载时解析,而是在调用resolve() 时才解析。如果将 loadHints 设置为ResolveAllSymbolsHint ,那么在平台支持的情况下,所有符号都将在加载时解析。
设置ExportExternalSymbolsHint 将使库中的外部符号可在后续加载的库中解析。
如果设置了LoadArchiveMemberHint ,文件名将由两部分组成:一个是对归档文件的引用路径,第二个是对归档成员的引用。例如,fileName libGL.a(shr_64.o)
将指向名为libGL.a
的归档文件中的库shr_64.o
。这仅支持 AIX 平台。
加载提示的解释与平台有关,如果您使用它,很可能会对您编译的平台做出一些假设,因此只有在您了解其后果的情况下才能使用它们。
默认情况下,这些标志均未设置,因此在加载库时将采用懒符号解析,不会导出外部符号供其他动态加载的库解析。
注意: 只有当该对象未与文件关联时,才能清除提示。只有设置文件名后才能添加提示(hints 将使用旧的提示)。
注意: 在加载程序库后设置此属性不会产生任何影响,loadHints() 也不会反映这些更改。
注: 该属性在引用同一程序库的所有QLibrary 实例中共享。
访问函数:
QLibrary::LoadHints | loadHints() const |
void | setLoadHints(QLibrary::LoadHints hints) |
成员函数文档
[explicit]
QLibrary::QLibrary(QObject *parent = nullptr)
用给定的parent 构建一个库。
[explicit]
QLibrary::QLibrary(const QString &fileName, QObject *parent = nullptr)
用给定的parent 构造一个库对象,加载fileName 指定的库。
我们建议在fileName 中省略文件的后缀,因为 QLibrary 会根据平台自动查找具有相应后缀的文件,例如 Unix 上的".so"、macOS 和 iOS 上的".dylib "以及 Windows 上的".dll"。(请参见fileName 。)
[explicit]
QLibrary::QLibrary(const QString &fileName, const QString &version, QObject *parent = nullptr)
使用给定的parent 构建一个库对象,该对象将加载由fileName 和完整版本号version 指定的库。目前,版本号在 Windows 上被忽略。
我们建议在fileName 中省略文件后缀,因为 QLibrary 会根据平台自动查找相应后缀的文件,例如 Unix 上的".so"、macOS 和 iOS 上的".dylib "以及 Windows 上的".dll"。(请参见fileName 。)
[explicit]
QLibrary::QLibrary(const QString &fileName, int verNum, QObject *parent = nullptr)
使用给定的parent 构建一个库对象,该对象将加载由fileName 和主要版本号verNum 指定的库。目前,版本号在 Windows 上被忽略。
我们建议在fileName 中省略文件后缀,因为 QLibrary 会根据平台自动查找相应后缀的文件,例如 Unix 上的".so"、macOS 和 iOS 上的".dylib "以及 Windows 上的".dll"。(请参见fileName 。)
[virtual noexcept]
QLibrary::~QLibrary()
销毁QLibrary 对象。
除非明确调用unload() ,否则程序库将保留在内存中,直至应用程序终止。
QString QLibrary::errorString() const
返回一个文本字符串,其中包含对上次发生的错误的描述。目前,只有当load(),unload() 或resolve() 因故失败时,才会设置 errorString。
[static]
bool QLibrary::isLibrary(const QString &fileName)
如果fileName 具有可加载库的有效后缀,则返回true
;否则返回false
。
平台 | 有效后缀 |
---|---|
Windows | .dll ,.DLL |
Unix/Linux | .so |
AIX | .a |
HP-UX | .sl ,.so (HP-UXi) |
MacOS 和 iOS | .dylib ,.bundle 、.so |
Unix 上的版本号尾部会被忽略。
bool QLibrary::isLoaded() const
如果load() 成功,则返回true
;否则返回false
。
另请参阅 load()。
bool QLibrary::load()
加载程序库,如果程序库加载成功,则返回true
;否则返回false
。由于resolve() 总是在解析任何符号之前调用该函数,因此无需明确调用。在某些情况下,您可能希望提前加载程序库,这时就需要使用此函数。
另请参见 unload()。
QFunctionPointer QLibrary::resolve(const char *symbol)
返回导出符号symbol 的地址。如有必要,将加载程序库。如果无法解析符号或无法加载库,则函数返回nullptr
。
示例
typedef int (*AvgFunction)(int, int); AvgFunction avg = (AvgFunction) library->resolve("avg"); if (avg) return avg(5, 8); else return -1;
符号必须作为 C 函数从库中导出。这意味着,如果使用 C++ 编译器编译库,则必须用extern "C"
封装该函数。在 Windows 下,还必须使用__declspec(dllexport)
编译器指令从 DLL 中显式导出函数,例如
extern "C" MY_EXPORT int avg(int a, int b) { return (a + b) / 2; }
MY_EXPORT
定义为
#ifdef Q_OS_WIN #define MY_EXPORT __declspec(dllexport) #else #define MY_EXPORT #endif
[static]
QFunctionPointer QLibrary::resolve(const QString &fileName, const char *symbol)
这是一个重载函数。
加载库fileName 并返回导出符号symbol 的地址。请注意,fileName 不应包含特定平台的文件后缀;(参见fileName )。该库将一直加载到应用程序退出为止。
如果无法解析符号或无法加载库,函数将返回nullptr
。
另请参阅 resolve() 。
[static]
QFunctionPointer QLibrary::resolve(const QString &fileName, const QString &version, const char *symbol)
这是一个重载函数。
加载具有完整版本号version 的库fileName ,并返回导出符号symbol 的地址。请注意,fileName 不应包含特定平台的文件后缀;(参见fileName )。在 Windows 系统中,version 将被忽略。
如果无法解析符号或无法加载库,函数将返回nullptr
。
另请参阅 resolve() 。
[static]
QFunctionPointer QLibrary::resolve(const QString &fileName, int verNum, const char *symbol)
这是一个重载函数。
加载主要版本号为verNum 的库fileName ,并返回导出符号symbol 的地址。请注意,fileName 不应包含特定平台的文件后缀;(参见fileName )。在 Windows 系统中,verNum 将被忽略。
如果无法解析符号或无法加载库,函数将返回nullptr
。
另请参阅 resolve() 。
void QLibrary::setFileNameAndVersion(const QString &fileName, const QString &version)
将fileName 属性和完整版本号分别设置为fileName 和version 。在 Windows 系统中,version 参数将被忽略。
另请参阅 setFileName().
void QLibrary::setFileNameAndVersion(const QString &fileName, int versionNumber)
将fileName 属性和主要版本号分别设置为fileName 和versionNumber 。在 Windows 系统中,versionNumber 将被忽略。
另请参阅 setFileName().
bool QLibrary::unload()
卸载程序库,如果程序库可以卸载,则返回true
;否则返回false
。
卸载会在应用程序终止时自动进行,因此通常不需要调用此函数。
如果QLibrary 的其他实例正在使用相同的库,则调用将失败,只有当每个实例都调用 unload() 后才会卸载。
请注意,在 macOS 上,动态链接库无法卸载。QLibrary::unload() 将返回true
,但库仍将加载到进程中。
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.