dlopen 子例程

用途

动态地将模块装入到调用进程中。

语法

#include <dlfcn.h>
void *dlopen (FilePath, Flags);
const char *FilePath;
int Flags;

描述

dlopen 子例程将 FilePath 指定的模块装入正在执行的进程的地址空间中。 模块的从属项也会自动装入。 如果已装入该模块,那么不会再次装入该模块,但 dlopen 子例程将返回新的唯一值。

dlopen 子例程是动态装入共享库的可移植方法。 它对它装入的模块执行 C++ 静态初始化,就像 loadAndInit 子例程那样。

dlopen 返回的值可能用于后续调用 dlsymdlclose。 如果在操作期间发生错误,那么 dlopen 将返回NULL.

如果使用 -brtl 选项链接了主应用程序,那么运行时链接程序由 dlopen调用。 如果正在装入的模块已在启用运行时链接的情况下链接,那么模块内引用和模块间引用都将被主应用程序中可用的任何符号覆盖。 如果已启用运行时链接,但未启用模块构建,那么将覆盖所有模块间引用,但不会覆盖某些模块内引用。

如果首次装入使用 dlopen 或其任何从属项打开的模块,那么将在 dlopen 返回之前调用这些新装入的例程的初始化例程 (在运行时链接之后 (如果适用))。 初始化例程是在构建模块时使用 -binitfini: 链接程序选项指定的函数。 (请参阅 ld 命令以获取有关此选项的更多信息。)

调用所有新装入的模块的初始化函数后,将执行 C++ 静态初始化。 如果从初始化函数或 C++ 静态初始化函数中调用 dlopen 子例程,那么可以先初始化嵌套的 dlopen 子例程装入的模块,然后再完全初始化最初装入的模块。

如果从 binitfini 函数中调用 dlopen 子例程,那么将放弃对其他模块初始化当前模块。

注: 如果要装入的模块具有读其他许可权,那么会将该模块装入到全局共享库段中。 即使不再使用装入到全局共享库段中的模块,也不会卸载这些模块。 使用 slibclean 命令从全局共享库段中除去未使用的模块。 要在进程专用区域中装入模块,请使用 slibclean 命令完全卸载模块,然后取消设置其读许可权。

LIBPATHLD_LIBRARY_PATH 环境变量可用于指定 dlopen 子例程在其中搜索指定模块的目录列表。 正在运行的应用程序还包含链接应用程序时指定的一组库搜索路径。 dlopen 子例程根据 load 子例程定义的机制搜索模块,因为 dlopen 子例程在内部使用 L_LIBPATH_EXEC 标志调用 load 子例程。

描述
FilePath 指定包含可装入模块的文件的名称。 此参数可以包含绝对路径,相对路径或无路径部分。 如果 FilePath 包含斜杠字符,那么将直接使用 FilePath ,并且不会搜索任何目录。

如果 FilePath 参数是/unixdlopen 返回可用于在当前内核映像中查找符号的值,包括在进程开始执行时可用的任何内核扩展中找到的那些符号。

如果 FilePath 的值是NULL,将返回主应用程序的值。 这允许动态装入的对象在主可执行文件中查找符号,或者允许应用程序检查自身中可用的符号。

标志

指定 dlopen行为的变体。 必须始终指定 RTLD_NOWRTLD_LAZY 。 其他标志可以与 RTLD_NOWRTLD_LAZY配合使用。

描述
RTLD_NOW 装入要装入的模块的所有从属项并解析所有符号。
RTLD_LAZY 指定与 RTLD_NOW相同的行为。 在操作系统的未来发行版中, RTLD_LAZY 的行为可能会更改,以便延迟某些符号的解析来装入从属模块。
RTLD_GLOBAL 允许在解析其他 dlopen 调用所使用的符号时显示正在装入的模块中的符号。 当使用 dlopen(NULL , mode) 打开主应用程序时,也会显示这些符号。
RTLD_LOCAL 在解析其他 dlopen 调用所使用的符号时,阻止装入模块中的符号。 只能通过调用 dlsym 子例程来访问正在装入的模块中的符号。 如果既未指定 RTLD_GLOBAL ,也未指定 RTLD_LOCAL ,那么缺省值为 RTLD_LOCAL。 如果同时指定了这两个标志,那么将忽略 RTLD_LOCAL
RTLD_MEMBER dlopen 子例程可用于装入作为归档成员的模块。 当调用 load 子例程时,将使用 L_LOADMEMBER 标志。 模块名称 FilePath 根据 load 子例程中概述的规则来命名归档和归档成员。
RTLD_NOAUTO延迟 防止要装入的模块中的延迟导入被后续装入自动解析。 当调用 load 子例程时,将使用 L_NOAUTO延迟 标志。

通常,为供 dlopendlsym 子例程使用而构建的模块将不包含延迟导入。 但是,仍可以使用延迟导入。 使用 dlopen 打开的模块可以为主应用程序中的延迟导入提供定义,为使用 load 子例程装入的模块提供定义 (如果未使用 L_NOAUTODEFERRED 标志) 以及为使用 dlopen 子例程装入的其他模块提供定义 (如果未使用 RTLD_NOAUTODEFERRED 标志)。

返回值

成功完成后, dlopen 将返回一个可在对 dlsymdlclose 子例程的调用中使用的值。 该值对于与 loadbind卸载 子例程配合使用无效。

如果 dlopen 调用失败,NULL(值为 0) ,并设置全局变量 errno 。 如果 errno 包含值ENOEXEC,可通过 dlerror 函数获取更多信息。

错误代码

请参阅 load 子例程以获取可能的 errno 值及其含义的列表。