链接程序和库指南

装入其他目标文件

使用 dlopen(3C),可将其他目标文件添加到运行的进程的地址空间。此函数将路径名和绑定模式作为参数,并向应用程序返回一个句柄。通过 dlsym(3C),可使用此句柄来查找供应用程序使用的符号。

如果将路径名指定为 简单文件名(名称中没有 '/'),则运行时链接程序将使用一组规则来生成相应的路径名。包含 '/' 的路径名均按原样使用。

这些搜索路径规则与用于查找所有初始依赖项的规则完全相同。 请参见运行时链接程序搜索的目录。例如,文件 main.c 包含以下代码片段。


#include        <stdio.h>

#include        <dlfcn.h>

 

main(int argc, char ** argv)

{

        void *  handle;

        .....

 

        if ((handle = dlopen("foo.so.1", RTLD_LAZY)) == NULL) {

                (void) printf("dlopen: %s\n", dlerror());

                exit (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) 指定的任何共享库。有关版本化的更多信息,请参见协调版本化文件名


如果找不到所需目标文件,则 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((const char *)0, RTLD_LAZY)) == NULL) {

则通过指定了 RTLD_GLOBAL 标志的 dlopen(3C),可使用从 dlopen(3C) 返回的句柄在应用程序本身、进程初始化时装入的任何依赖项或添加到进程地址空间的所有目标文件中查找符号。