使用 dlopen(3C),可将其他目标文件添加到运行的进程的地址空间。此函数将路径名和绑定模式作为参数,并向应用程序返回一个句柄。通过 dlsym(3C),可使用此句柄来查找供应用程序使用的符号。
如果将路径名指定为简单文件名(名称中没有 "/"),则运行时链接程序将使用一组规则来生成相应的路径名。包含 "/" 的路径名均按原样使用。
这些搜索路径规则与用于查找所有初始依赖项的规则完全相同。请参见运行时链接程序搜索的目录。例如,文件 main.c 包含以下代码片段。
#include <stdio.h> #include <dlfcn.h> int main(int argc, char **argv) { void *handle; .... if ((handle = dlopen("foo.so.1", RTLD_LAZY)) == NULL) { (void) printf("dlopen: %s\n", dlerror()); return (1); } ....
要查找共享目标文件 foo.so.1,运行时链接程序应使用进程初始化时存在的 LD_LIBRARY_PATH 定义。接下来,使用链接编辑 prog 过程中指定的运行路径。最后,使用缺省位置 /lib 和 /usr/lib(对于 32 位目标文件)或 /lib/64 和 /usr/lib/64(对于 64 位目标文件)。
如果将路径名指定为:
if ((handle = dlopen("./foo.so.1", RTLD_LAZY)) == NULL) {
则运行时链接程序只会在进程的当前工作目录中搜索该文件。
如果无法找到需要的目标文件,dlopen(3C) 将返回 NULL 句柄。在此情况下,可使用 dlerror(3C) 来显示失败的真正原因。例如:
$ cc -o prog main.c $ prog dlopen: ld.so.1: prog: fatal: foo.so.1: open failed: No such file or directory
如果 dlopen(3C) 添加的目标文件依赖于其他目标文件,则也会将这些目标文件引入进程的地址空间中。此进程将一直继续,直到装入指定目标文件的所有依赖项。此依赖项树称为组。
如果 dlopen(3C) 指定的目标文件或其任何依赖项已经是进程映像的一部分,则不会进一步处理这些目标文件,而是向应用程序返回一个有效句柄。此机制可避免多次装入同一目标文件,并且使应用程序可以获取指向自身的句柄。例如,前面的示例 main.c 可以包含以下 dlopen() 调用。
if ((handle = dlopen(0, RTLD_LAZY)) == NULL) {
通过指定了 RTLD_GLOBAL 标志的 dlopen(3C),可使用从该 dlopen(3C) 返回的句柄在应用程序本身、进程初始化时装入的任何依赖项或添加到进程地址空间的所有目标文件中查找符号。