在 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,则加分。 :-)
最佳答案
我认为 dladdr
函数可以满足您的需求。从手册页:
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;
If no symbol matching addr could be found, then
dli_sname
anddli_saddr
are set toNULL
.
dladdr()
returns 0 on error, and non-zero on success.
所以你只要给它一个函数指针(比如构造函数本身的地址),它就会给你文件名和一堆其他信息。下面是一些示例代码:
#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 上,具有相同的语义。
关于Linux:如何获取刚刚从构造函数加载的共享对象的全名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1642128/