动态加载时的库路径? [英] library path when dynamically loaded?

查看:103
本文介绍了动态加载时的库路径?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何从库本身中获取共享库的路径?

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_snamedli_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆