8

在 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,则额外加分。:-)

4

2 回答 2

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_snamedli_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 上,具有相同的语义。

于 2009-10-29T23:35:12.823 回答
1

一种极其丑陋和可怕的方法是查看 /proc/pid/maps 并查找包含on_load正在执行的函数地址的映射。

于 2009-10-29T08:43:12.030 回答