8 linux dll constructor shared object
在Windows上,几个参数传递给DllMain构造函数:
BOOL WINAPI DllMain(
__in HINSTANCE hinstDLL,
__in DWORD fdwReason,
__in LPVOID lpvReserved
);
Run Code Online (Sandbox Code Playgroud)
从hinstDLL我可以使用GetModuleFileName()获取DLL本身的完全限定文件名:
LPTSTR str = new TCHAR[256];
int libNameLength = GetModuleFileName(hinstDLL, str, 256);
delete[] str;
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,str现在包含刚加载的DLL的全名,例如C:\ Windows\System32\MyFile.dll.
在Linux上,没有参数传递给共享对象构造函数:
void `__attribute__` ((constructor)) on_load(void);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,如何获取DLL的全名?如果您的解决方案也适用于Mac,则可获得额外的荣 :-)
我认为该dladdr
功能可能会满足您的要求。从手册页:
函数 dladdr() 接受一个函数指针并尝试解析它所在的名称和文件。信息存储在
Dl_info
结构中:Run Code Online (Sandbox Code Playgroud)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);
}
Run Code Online (Sandbox Code Playgroud)
编辑:看起来这个函数也存在于 OS X 上,具有相同的语义。