在c ++(linux)中获取动态库目录

时间:2015-10-15 14:30:47

标签: c++ linux

是否有任何编程方式来获取程序加载的动态库的位置?

我知道可以获得可执行文件'跑道。但这对我来说还不够。

我正在开发一个具有一些依赖关系的外部库,我需要相应地指出它的位置。

例如,程序运行于:

/local/deepLearning/bin

此程序使用位于以下位置的动态库:

/local/external/libs/faciesAnalysis

我需要的是,在运行时,字符串

"/local/external/libs/facesAnalysis"

我正在研究linux,有什么建议吗?

3 个答案:

答案 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