我很好奇在Linux中使用dlopen
来调用共享库。
假设我想在C中使用名为fileName.so
的共享库。我在64位Ubuntu Linux中工作,我包含dlfcn.h
并使用dlopen
函数来访问共享库。
当我使用dlopen(fileName.so, RTLD_LAZY)
时,返回NULL句柄并且不打开共享库。但是,当我使用dlopen("./fileName.so", RTLD_LAZY)
时dlopen
完成其工作并打开共享库。似乎主要的一点是在文件名之前使用./
。
如果能帮助我找出为什么我应该在代码中使用./
,我们将不胜感激。感谢
答案 0 :(得分:5)
POSIX说dlopen()
必须知道在哪里查找文件,并在文件名不包含定义的/
实现时保留行为。在Linux上,如果你没有提供路径名(某个地方带有/
的名称),那么dlopen()
只会查找由环境变量(如LD_LIBRARY_PATH)或{ {1}}(或/etc/ld.so.conf
;另请参阅/etc/ld.so.cache
)或标准地点,例如ldconfig(8)
和/lib
。
当你指定相对名称/usr/lib
时,它知道要查看当前目录,这通常不是它看起来的地方。
请注意,您可以在支持32位和64位可执行文件的系统上遇到一些有趣的问题,其中各种约定用于不同类库的位置。 Unix的其他变体使用模糊相关的系统 - 目前大多使用./fileName.so
等(历史上,并非总是这样),并使用各种环境变量(DYLD_LIBRARY_PATH,LIBPATH,SHLIB_PATH,LD_RUN_PATH,LD_LIBRARY_PATH_32,LD_LIBRARY_PATH_64) ,...)。
答案 1 :(得分:1)
./
是.so
文件的相对路径。这意味着该文件位于当前目录中。
在* nix中,默认情况下,如果给定的文件名没有绝对路径或相对路径,dlopen
将在集合list of default locations中搜索库。
答案 2 :(得分: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"