动态加载时的库路径? [英] library path when dynamically loaded?
问题描述
如何从库本身中获取共享库的路径?
How can I get the path of the shared library from within the library itself?
换句话说,假设库X是使用dlopen()
加载的,我如何从该库本身内部访问用于加载该库的路径?
In other words, let's say that library X is loaded using dlopen()
, how can I get access to the path that was used to load the said library from within the library itself?
请注意,我无法首先将加载库的代理交给该参数.
Note that I cannot have the agent that loaded the library in the first place hand me this parameter.
更新:这是使用静态变量的方法:
UPDATED: Here is way that works with static variables:
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):
The dynamic linker actually searches several places to find each dynamic library. These include (from man ld.so):
- 环境变量
LD_LIBRARY_PATH
给出的路径
- 烘焙到二进制文件中的路径会在
DT_RUNPATH
条目下加载该库 - 缓存文件/etc/ld.so.cache
- /lib和/usr/lib
- Paths given by the environment variable
LD_LIBRARY_PATH
- Paths baked into the binary load the library under the
DT_RUNPATH
entry - The cache file /etc/ld.so.cache
- /lib and /usr/lib
如果要获取特定共享库的路径,建议使用dladdr
函数.在手册页中:
If you want to get the path for a specific shared library, I would recommend the dladdr
function. From the man page:
函数dladdr()使用函数指针并尝试解析 名称和文件所在的位置.信息存储在
Dl_info
结构:
The function dladdr() takes a function pointer and tries to resolve name and file where it is located. Information is stored in the
Dl_info
structure:
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
.
If no symbol matching addr could be found, then dli_sname
and
dli_saddr
are set to NULL
.
dladdr()
出错时返回0,成功时返回非零.
dladdr()
returns 0 on error, and non-zero on success.
因此,您只给它一个函数指针,它将给您提供文件的名称以及其他信息.因此,例如,您可以在库中有一个构造函数,对其本身进行调用以找出库的完整路径:
So you just give it a function pointer, and it will give you the name of the file which supplies it and a bunch of other information. So for instance, you could have a constructor in a library call this on itself to find out the full path of the library:
#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上也可以使用.
This function also works on OS X with the same semantics.
这篇关于动态加载时的库路径?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!