Linux:如何获取刚刚从构造函数加载的共享对象的全名?

时间:2009-10-29 07:34:09

标签: linux dll object constructor shared

在Windows上,几个参数传递给DllMain构造函数:

BOOL WINAPI DllMain(  
  __in  HINSTANCE hinstDLL,  
  __in  DWORD fdwReason,  
  __in  LPVOID lpvReserved  
);

从hinstDLL我可以使用GetModuleFileName()获取DLL本身的完全限定文件名:

LPTSTR str = new TCHAR[256];  
int libNameLength = GetModuleFileName(hinstDLL, str, 256);  
delete[] str;  

在上面的示例中,str现在包含刚刚加载的DLL的全名,例如C:\ Windows \ System32 \ MyFile.dll。

在Linux上,没有参数传递给共享对象构造函数:

void `__attribute__` ((constructor)) on_load(void);

在这种情况下,如何获取DLL的全名?如果您的解决方案也适用于Mac,则可获得额外的荣: - )

2 个答案:

答案 0 :(得分:4)

我认为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;
     

如果找不到匹配addr的符号,那么dli_sname和   dli_saddr设置为NULL

     

dladdr()出错时返回0,成功时返回非零。

所以你只需给它一个函数指针(就像构造函数本身的地址一样),它会给你文件名和一堆其他信息。这是一些示例代码:

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

__attribute__((constructor))
void on_load(void) {
    Dl_info dl_info;
    dladdr(on_load, &dl_info);
    fprintf(stderr, "module %s loaded\n", dl_info.dli_fname);
}

编辑:看起来这个函数也存在于OS X上,具有相同的语义。

答案 1 :(得分:1)

这样做的一个非常丑陋和可怕的方法是查看/ proc / pid / maps并查找包含正在执行的on_load函数的地址的映射。