如何从库本身中获取共享库的路径?
换句话说,假设使用来加载库X dlopen(),如何从库本身内部访问用于加载所述库的路径?
dlopen()
请注意,我不能首先将这个库加载到该库中。
更新: 这是使用静态变量的方法:
std::string wdir; namespace { class dynamic_library_load_unload_handler { public: dynamic_library_load_unload_handler(){ Dl_info dl_info; dladdr((void *) NP_Initialize, &dl_info); std::string path(dl_info.dli_fname); wdir = path.substr( 0, path.find_last_of( '/' ) +1 ); } ~dynamic_library_load_unload_handler(){ // Code to execute when the library is unloaded } } dynamic_library_load_unload_handler_hook; }
动态链接器实际上搜索几个位置以找到每个动态库。其中包括(来自man ld.so):
LD_LIBRARY_PATH
DT_RUNPATH
如果要获取特定共享库的路径,建议使用此dladdr功能。从手册页:
dladdr
函数dladdr()使用函数指针,并尝试解析其所在的名称和文件。信息存储在 Dl_info结构中: typedef struct { const char *dli_fname; /* Pathname of shared object that contains address */ void *dli_fbase; /* Address at which shared object is loaded */ const char *dli_sname; /* Name of nearest symbol with address lower than addr */ void *dli_saddr; /* Exact address of symbol named in dli_sname */ } Dl_info; 如果找不到与符号匹配的地址,则将dli_sname和 dli_saddr设置为NULL。 dladdr() 错误时返回0,成功时返回非零。
函数dladdr()使用函数指针,并尝试解析其所在的名称和文件。信息存储在 Dl_info结构中:
Dl_info
typedef struct { const char *dli_fname; /* Pathname of shared object that contains address */ void *dli_fbase; /* Address at which shared object is loaded */ const char *dli_sname; /* Name of nearest symbol with address lower than addr */ void *dli_saddr; /* Exact address of symbol named in dli_sname */ } Dl_info;
如果找不到与符号匹配的地址,则将dli_sname和 dli_saddr设置为NULL。
dli_sname
dli_saddr
NULL
dladdr() 错误时返回0,成功时返回非零。
dladdr()
因此,您只给它一个函数指针,它将给您提供文件的名称以及其他信息。因此,例如,您可以在库中有一个构造函数,对其自身进行调用以找出库的完整路径:
#define _GNU_SOURCE #include <dlfcn.h> #include <stdio.h> __attribute__((constructor)) void on_load(void) { Dl_info dl_info; dladdr((void *)on_load, &dl_info); fprintf(stderr, "module %s loaded\n", dl_info.dli_fname); }
此功能也可以在具有相同语义的OS X上使用。