You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取dlopen函数实际加载的动态库完整文件路径?

获取dlopen加载库的实际完整路径

当你用dlopen("foo", RTLD_NOW)或RTLD_LAZY加载动态库后,想要获取实际加载的完整路径,可以用以下几种方法:

方法1:借助dladdr()函数

dladdr()可以通过符号地址反查所属库的信息。步骤如下:

  • 先用dlsym()从已获取的句柄中,拿到库内任意一个导出函数(或全局变量)的地址;
  • 调用dladdr()传入该地址,从返回的Dl_info结构体中提取dli_fname字段,就是库的完整路径。

示例代码:

#include <dlfcn.h>
#include <stdio.h>

int main() {
    void* handle = dlopen("foo", RTLD_NOW);
    if (!handle) {
        fprintf(stderr, "%s\n", dlerror());
        return 1;
    }

    // 替换为库中实际存在的导出函数名
    void (*target_func)() = dlsym(handle, "foo_exported_func");
    if (!target_func) {
        fprintf(stderr, "%s\n", dlerror());
        dlclose(handle);
        return 1;
    }

    Dl_info info;
    if (dladdr(target_func, &info)) {
        printf("实际加载路径:%s\n", info.dli_fname);
    } else {
        fprintf(stderr, "无法获取路径:%s\n", dlerror());
    }

    dlclose(handle);
    return 0;
}

方法2:解析/proc/self/maps(Linux专属)

Linux系统中,/proc/self/maps文件记录了进程所有内存映射的详细信息,包括已加载动态库的路径。可以通过以下步骤提取:

  • 先通过dladdr()获取库的基地址;
  • 打开/proc/self/maps逐行读取,找到包含基地址的内存区间行,该行末尾就是库的完整路径。

示例代码片段:

#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>

void get_lib_path_from_proc_maps(void* handle) {
    Dl_info info;
    if (!dladdr(dlsym(handle, ""), &info)) {
        fprintf(stderr, "%s\n", dlerror());
        return;
    }
    void* lib_base = info.dli_fbase;

    FILE* maps_file = fopen("/proc/self/maps", "r");
    if (!maps_file) {
        perror("打开/proc/self/maps失败");
        return;
    }

    char line_buf[1024];
    while (fgets(line_buf, sizeof(line_buf), maps_file)) {
        void* map_start, *map_end;
        char lib_path[1024];
        if (sscanf(line_buf, "%p-%p %*s %*s %*s %*s %s", &map_start, &map_end, lib_path) == 3) {
            if (lib_base >= map_start && lib_base < map_end) {
                printf("实际加载路径:%s\n", lib_path);
                break;
            }
        }
    }

    fclose(maps_file);
}

方法3:使用dlinfo()函数(部分系统支持)

Linux、BSD等系统提供了dlinfo()函数,可直接通过dlopen句柄获取库路径。需要借助link_map结构体:

示例代码:

#include <dlfcn.h>
#include <link.h>
#include <stdio.h>

int main() {
    void* handle = dlopen("foo", RTLD_NOW);
    if (!handle) {
        fprintf(stderr, "%s\n", dlerror());
        return 1;
    }

    struct link_map* link_info;
    if (dlinfo(handle, RTLD_DI_LINKMAP, &link_info) == 0) {
        printf("实际加载路径:%s\n", link_info->l_name);
    } else {
        fprintf(stderr, "调用dlinfo失败:%s\n", dlerror());
    }

    dlclose(handle);
    return 0;
}

内容的提问来源于stack exchange,提问作者einpoklum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 20:06:25