linux环境 dladdr realpath函数为什么获取到的是相对路径不是绝对路径
时间: 2024-05-23 20:16:10 浏览: 249
可能是因为你传递给 `dladdr` 或 `realpath` 函数的路径是相对路径,导致返回的也是相对路径。这两个函数只能处理传入的路径,无法自动转换成绝对路径。
如果你需要获取绝对路径,可以使用 `getcwd` 函数获取当前工作目录,然后将相对路径拼接上去,得到完整的绝对路径。或者使用 `realpath` 函数的第一个参数传入绝对路径,这样就可以获取到绝对路径了。
相关问题
linux环境 dladdr函数为什么获取到的是相对路径不是绝对路径
`dladdr` 函数可以返回指定地址所在的动态链接库(shared object)的信息,包括库的名称、基地址等等。在 Linux 环境中,`dladdr` 函数获得的库的名称是相对路径而不是绝对路径,这是因为 Linux 环境中的共享库一般被安装到系统默认的位置,例如 `/usr/lib` 或 `/usr/local/lib` 等目录下。因此,相对路径已经足够描述共享库的位置信息。
如果想获取绝对路径,可以使用 `realpath` 函数将相对路径转换为绝对路径。例如:
```c
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
void *handle = dlopen("libtest.so", RTLD_NOW);
if (handle) {
Dl_info info;
if (dladdr(handle, &info)) {
char *abs_path = realpath(info.dli_fname, NULL);
printf("Absolute path: %s\n", abs_path);
free(abs_path);
}
dlclose(handle);
}
return 0;
}
```
这段代码会输出共享库 `libtest.so` 的绝对路径。
linux环境 调用dladdr函数为什么获取不到绝对路径
`dladdr` 函数可以用于获取动态链接库的相关信息,包括库的名称、基址和符号地址等。但是它不能直接获取动态链接库的绝对路径,因为在 Linux 系统中,动态链接库的加载路径可能是多个,而且在加载时可能会被重定位到其他位置。
如果你需要获取动态链接库的绝对路径,可以尝试使用 `dl_iterate_phdr` 函数来遍历所有加载的动态链接库,然后判断哪个库的基址等于给定的符号地址,然后获取该库的绝对路径。
这里是一个示例代码:
```c
#include <dlfcn.h>
#include <link.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void *get_func_addr(const char *lib_path, const char *func_name) {
void *lib_handle = dlopen(lib_path, RTLD_LAZY);
if (!lib_handle) {
fprintf(stderr, "Failed to open %s: %s\n", lib_path, dlerror());
return NULL;
}
void *func_addr = dlsym(lib_handle, func_name);
if (!func_addr) {
fprintf(stderr, "Failed to find symbol %s in %s: %s\n", func_name, lib_path, dlerror());
dlclose(lib_handle);
return NULL;
}
struct dl_phdr_info info;
memset(&info, 0, sizeof(info));
info.dlpi_name = lib_path;
dl_iterate_phdr(
[](struct dl_phdr_info *info, size_t size, void *data) {
if (info->dlpi_addr == reinterpret_cast<uintptr_t>(data)) {
char *path = realpath(info->dlpi_name, NULL);
if (path) {
printf("Library %s path: %s\n", info->dlpi_name, path);
free(path);
}
return 1;
}
return 0;
},
func_addr);
dlclose(lib_handle);
return func_addr;
}
int main() {
void (*hello)() = reinterpret_cast<decltype(hello)>(get_func_addr("./libhello.so", "hello"));
if (hello) {
hello();
}
return 0;
}
```
这个示例代码可以在加载 `libhello.so` 库时输出它的绝对路径。注意,在遍历 `dl_phdr_info` 结构体时,我们需要判断 `info->dlpi_addr` 是否等于 `hello` 函数的地址,以确定哪个库包含了该函数。同时,我们还调用了 `realpath` 函数获取库的绝对路径。
阅读全文