1

我很好奇dlopen在 Linux 中使用来调用共享库。假设我想在 C 中使用一个名为fileName.so. 我在 64 位 Ubuntu Linux 中工作,我包含dlfcn.h并使用dlopen函数来访问共享库。

当我使用 时dlopen(fileName.so, RTLD_LAZY),会返回一个 NULL 句柄并且不会打开共享库。但是,当我使用它时dlopen("./fileName.so", RTLD_LAZY)dlopen它会完成它的工作并打开共享库。似乎重点是在./文件名之前使用。

如果帮助我弄清楚为什么我应该./在我的代码中使用,我们将不胜感激。谢谢

4

3 回答 3

5

POSIX 表示dlopen()必须知道在哪里查找文件并在文件名不包含/定义的实现时保留行为。在 Linux 上,如果您不提供路径名(/在某处带有 a 的名称),则dlopen()仅在“标准位置”中查找,由环境变量指定,例如 LD_LIBRARY_PATH 或 via /etc/ld.so.conf(或/etc/ld.so.cache;另请参见ldconfig(8))或标准位置,例如作为/lib/usr/lib

当您指定相对名称./fileName.so时,它知道在当前目录中查找,这通常不是它查找的位置。

请注意,在支持 32 位和 64 位可执行文件的系统上,您可能会遇到一些有趣的问题,不同类库的位置使用了各种约定。Unix 的其他变体使用模糊相关的系统——dlopen()现在主要使用 et al(从历史上看,并非总是如此),并使用各种各样的环境变量(DYLD_LIBRARY_PATH、LIBPATH、SHLIB_PATH、LD_RUN_PATH、LD_LIBRARY_PATH_32、LD_LIBRARY_PATH_64,...) .

于 2013-02-04T05:55:16.397 回答
1

./.so文件的相对路径。这意味着该文件在当前目录中。

在 *nix 中,默认情况下,当给定一个没有绝对或相对路径的文件名时,将在一组默认位置列表中dlopen搜索库。

于 2013-02-04T05:55:39.017 回答
0

“要点”是在第二个示例中使用双引号:

    dlopen("./fileName.so", RTLD_LAZY)

如果您想包含您自己的库/文件名,请将其括在双引号中。./正如建议的那样,只要文件位于当前目录中,您甚至不需要它./

根据 dlopen 手册页的示例:

    handle = dlopen("libm.so", RTLD_LAZY);
       if (!handle) {
           fprintf(stderr, "%s\n", dlerror());
           exit(EXIT_FAILURE);
       }

文件名用引号括起来。

但是,正如先前答案所指定的,dlopen 将在“标准”位置查找“包含”。在工作目录中包含库的另一种方法(尽管显然不是共享系统库)是使用预处理器指令,文件名用双引号括起来:

#include <stdio.h>
#include <stdlib.h>
#include "myCustomLibrary.h"
于 2015-11-12T05:00:33.570 回答