QLibrary类
QLibrary类在运行时加载共享库。 更多...
头文件 | #include <QLibrary> |
CMake | find_package(Qt6 REQUIRED COMPONENTS Core) target_link_libraries(mytarget PRIVATE Qt6::Core) |
qmake | QT += core |
继承 | QObject |
- 包括继承成员在内的所有成员列表
- QLibrary是插件类的一部分。
注意: 此类中的所有函数都是重入的。
公共类型
enum | LoadHint { ResolveAllSymbolsHint, ExportExternalSymbolsHint, LoadArchiveMemberHint, PreventUnloadHint, DeepBindHint } |
flags | LoadHints |
属性
公共函数
QLibrary(QObject *parent = nullptr) | |
QLibrary(const QString &fileName, QObject *parent = nullptr) | |
QLibrary(const QString &fileName, int verNum, QObject *parent = nullptr) | |
QLibrary(const QString &fileName, const QString &version, 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, int versionNumber) |
void | setFileNameAndVersion(const QString &fileName, const QString &version) |
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, int verNum, const char *symbol) |
QFunctionPointer | resolve(const QString &fileName, const QString &version, const char *symbol) |
详细描述
QLibrary 对象的一个实例在单一共享目标文件上操作(我们将其称为“库”,但也称为“DLL”)。QLibrary 以平台无关的方式提供对库中功能访问。您可以在构造函数中传递一个文件名,或者通过setFileName()显式设置它。在加载库时,QLibrary 在所有系统特定的库位置中进行搜索(例如 Unix 上的 LD_LIBRARY_PATH
),除非文件名包含绝对路径。
如果文件名是一个绝对路径,QLibrary 会首先尝试加载此路径。如果找不到该文件,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();
为了让 resolve() 工作,符号必须从库中导出为一个 C 函数。这意味着如果库是用 C++ 编译器编译的,则该函数必须在 extern "C"
块中封装。在 Windows 上,这还需要使用 dllexport
宏;请参阅resolve() 了解如何执行此操作。为了方便,还有一个静态的 resolve() 函数,您可以使用它来调用库中的函数,而无需先显式加载库。
typedef void (*MyPrototype)(); MyPrototype myFunction = (MyPrototype) QLibrary::resolve("mylib", "mysymbol"); if (myFunction) myFunction();
另请参阅QPluginLoader.
成员类型文档
枚举 QLibrary::LoadHint
标志 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>的typedef。它存储LoadHint值的或组合。
另请参阅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()时懒惰解决(即,当调用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) |
成员函数文档
[显式]
QLibrary::QLibrary(QObject *parent = nullptr)
使用给定的 parent 构造库。
[显式]
QLibrary::QLibrary(const QString &fileName, QObject *parent = nullptr)
使用给定的 parent 和由 fileName 指定的库对象构造库。
我们建议在 fileName 中省略文件的扩展名,因为 QLibrary 会根据平台自动查找具有适当后缀的文件,例如 Unix 上的 ".so",macOS 和 iOS 上的 ".dylib",以及 Windows 上的 ".dll"。 (参见 fileName。)
[显式]
QLibrary::QLibrary(const QString &fileName, int verNum, QObject *parent = nullptr)
使用给定的 parent 和由 fileName 指定的库,并加载主版本号 verNum 的库对象。目前,在 Windows 上版本号被忽略。
我们建议在 fileName 中省略文件的扩展名,因为 QLibrary 会根据平台自动查找具有适当后缀的文件,例如 Unix 上的 ".so",macOS 和 iOS 上的 ".dylib",以及 Windows 上的 ".dll"。 (参见 fileName。)
[显式]
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。)
[虚拟 noexcept]
QLibrary::~QLibrary()
销毁 QLibrary 对象。
除非显式调用 unload(),否则库将保留在内存中,直到应用程序终止。
QString QLibrary::errorString() const
返回描述最后发生的错误文本字符串。目前,仅在 load(),unload() 或 resolve() 由于某些原因失败时,errorString 才会被设置。
[静态]
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
[静态]
QFunctionPointer QLibrary::resolve(const QString &fileName, const char *symbol)
这是一个重载函数。
加载库 fileName 并返回导出符号 symbol 的地址。请注意,fileName 不应包含特定平台的文件后缀;(请参阅 fileName)。库将在应用程序退出之前保持加载状态。
如果无法解析符号或无法加载库,则函数返回 nullptr
。
另请参阅:resolve ()。
[静态]
QFunctionPointer QLibrary::resolve(const QString &fileName, int verNum, const char *symbol)
这是一个重载函数。
加载名为 fileName 的库,主版本号为 verNum,并返回导出符号 symbol 的地址。注意 fileName 应当不包含平台特定的文件后缀;(见 fileName)。库将在应用程序退出之前保持加载状态。在 Windows 上忽略 verNum。
如果无法解析符号或无法加载库,则函数返回 nullptr
。
另请参阅:resolve ()。
[静态]
QFunctionPointer QLibrary::resolve(const QString &fileName, const QString &version, const char *symbol)
这是一个重载函数。
加载带有完整版本号 version 的库 fileName 并返回导出符号 symbol 的地址。注意 fileName 应当不包含平台特定的文件后缀;(见 fileName)。库将在应用程序退出之前保持加载状态。在 Windows 上忽略 version。
如果无法解析符号或无法加载库,则函数返回 nullptr
。
另请参阅:resolve ()。
void QLibrary::setFileNameAndVersion(const QString &fileName, int versionNumber)
设置 fileName 属性和主版本号分别为 fileName 和 versionNumber。在 Windows 上忽略 versionNumber。
另请参阅 setFileName。
void QLibrary::setFileNameAndVersion(const QString &fileName, const QString &version)
设置 fileName 属性和完整版本号分别为 fileName 和 version。在 Windows 上忽略 version 参数。
另请参阅 setFileName。
bool QLibrary::unload()
卸载库,如果库能够卸载则返回 true
,否则返回 false
。
在应用程序终止时此操作会自动发生,因此通常不需要调用此函数。
如果其他 QLibrary 实例正在使用同一库,则调用将失败,卸载只会在每个实例都已调用 unload() 的时候发生。
请注意,在 macOS 上,动态库不能卸载。QLibrary::unload() 将返回 true
,但库仍然保持在进程中加载。
© 2024 Qt公司。此处包含的文档贡献是各自所有者的版权。此处提供的文档根据自由软件基金会发布的 GNU自由文档许可协议版本1.3 的条款许可。Qt及其相关标志是芬兰和/或其他国家的 Qt 公司的商标。所有其他商标均为各自所有者的财产。