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

Get dynamic library directory in c++ (linux)

本文关键字:动态 c++ linux 获取      更新时间:2023-10-16

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

我知道有可能得到'可执行'的运行路径。但这对我来说还不够。

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

例如,程序运行在:

/local/deepLearning/bin

这个程序使用位于:

的动态库
/local/external/libs/faciesAnalysis
我需要的是,在运行时,字符串
"/local/external/libs/facesAnalysis"

我在linux上工作,有什么建议吗?

因为这是特定于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);
}

首先(这是特定于Linux的,因为是由内核提供的),您可以从程序内部解析/proc/self/maps伪文件。只要按顺序读取该文本文件的每一行,就可以获得每个mmap -ed文件的完整路径,包括共享库。请参阅proc(5)(并使用dirname(3)从路径中获取目录,也可以使用realpath(3)…)。阅读也打开(3)&ld-linux.so(8)并注意LD_LIBRARY_PATH/etc/ld.so.conf的作用

然后,这是特定于GNU libc的(但显然musl-libc也有),您可以对该库中的某些函数地址使用dladdr(3)。或者直接使用dl_iterate_phdr(3),它看起来完全符合您的问题。

小心奇怪的情况:一些程序可能会生成一个插件,然后dlopen(我的MELT就是这样做的),一些其他程序可能会在dlopen之后remove一个插件,一些程序可能是静态链接的,dlopen -ed插件可能已经被移动或重命名(也许是因为当你的程序正在运行时已经安装了一个新版本)…,同样的插件可以使用不同的路径进行符号链接和展开,等等…

阅读Drepper的论文:如何编写共享库

您可以获得可执行文件(std::string path_and_exe)的完整路径,然后执行以下命令:

#include <cstdlib>
std::string output("output.txt");
system ("ldd " + path_and_exe + " > " + output);
// read libray paths from output file