是否有任何编程方式来获取程序加载的动态库的位置?
我知道可以获得可执行文件'跑道。但这对我来说还不够。
我正在开发一个具有一些依赖关系的外部库,我需要相应地指出它的位置。
例如,程序运行于:
/local/deepLearning/bin
此程序使用位于以下位置的动态库:
/local/external/libs/faciesAnalysis
我需要的是,在运行时,字符串
"/local/external/libs/facesAnalysis"
我正在研究linux,有什么建议吗?
答案 0 :(得分:3)
由于这是专门用于Linux的操作系统,因此dladdr()
是dl
函数系列的glibc扩展,它将查找任何符号的文件名。将您知道的符号传递给您正在寻找的库中,您基本上已经完成了。
未进行适当的错误检查就提出了
#define _GNU_SOURCE
#include <dlfcn.h>
const char *my_fname(void) {
Dl_info dl_info;
dladdr((void*)my_fname, &dl_info);
return(dl_info.dli_fname);
}
答案 1 :(得分:1)
首先(这是Linux特有的,因为内核提供),您可以从程序内部解析/proc/self/maps
伪文件。只需顺序读取该文本文件的每一行,您就能够获得每个mmap
ed文件的完整路径,包括共享库。请参阅proc(5)(并使用dirname(3)从路径中获取目录,也许realpath(3) ...)。另请阅读dlopen(3)&amp; ld-linux.so(8)并注意LD_LIBRARY_PATH
和/etc/ld.so.conf
然后,这是特定于GNU libc(但显然musl-libc也有),您可以在该库的某些功能地址上使用dladdr(3)。或者只使用看起来非常适合您问题的dl_iterate_phdr(3)。
请注意奇怪的情况:某些程序可能会生成一个插件并且稍后会dlopen
(我的MELT正在执行that),其他一些程序可能remove
之后的插件dlopen
,某些程序可能是静态链接的,dlopen
- ed插件可能已被移动或重命名(可能是因为在程序运行时安装了新版本)...,相同的插件可能已经使用不同的路径进行符号链接和倾斜......等等。
阅读Drepper的论文:How To Write Shared Libraries
答案 2 :(得分:0)
您可以获得可执行文件的完整路径(std::string path_and_exe
),然后执行以下命令:
#include <cstdlib>
std::string output("output.txt");
system ("ldd " + path_and_exe + " > " + output);
// read libray paths from output file