问:如果我在共享库中编写DllMain()
函数,还有__attribute__((constructor))
函数,那么在加载库时会先执行哪一个函数?< / p>
问:如果我的链接到该共享库的可执行文件中包含__attribute__((constructor))
的函数,则首先调用的是 - 库的DllMain()
或可执行文件__attribute__((constructor))
功能
答案 0 :(得分:5)
A :按此顺序调用函数:
DLL constructor
DLL DllMain() (process attach)
EXE constructor
EXE main()
EXE main() ends
EXE destructor
DLL DllMain() (process detach)
DLL destructor
如果在运行时(LoadLibrary()
/ FreeLibrary()
)完成链接,则按以下顺序调用函数:
EXE constructor
EXE main()
EXE LoadLibrary()
DLL constructor
DLL DllMain() (process attach)
EXE main() continues
EXE FreeLibaray()
DLL DllMain() (process detach)
DLL destructor
EXE main() ends
EXE destructor
如果您忘记释放图书馆,则订单如下:
EXE constructor
EXE main()
EXE LoadLibrary()
DLL constructor
DLL DllMain() (process attach)
EXE main() continues
EXE main() ends
EXE destructor
EXE FreeLibaray() (system cleans up for you)
DLL DllMain() (process detach)
DLL destructor
答案 1 :(得分:0)
考虑代码
<强> EXE:强>
int main ()
{
printf("Executable Main, loading library\n");
#ifdef HAVE_WINDOWS
HMODULE lib = LoadLibraryA ("testdll.dll");
#elif defined(HAVE_LINUX)
void * lib = dlopen("testdll.so", RTLD_LAZY);
#endif
if (lib) {
printf("Executable Main, Freeing library\n");
#ifdef HAVE_WINDOWS
FreeLibrary (lib);
#elif defined(HAVE_LINUX)
dlclose(lib);
#endif
}
printf("Executable Main, exiting\n");
return 0;
}
<强> DLL 强>
struct Moo
{
Moo() { printf("DLL Moo, constructor\n"); }
~Moo() { printf("DLL Moo, destructor\n"); }
};
Moo m;
#ifdef HAVE_WINDOWS
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
printf("DllMain, DLL_PROCESS_ATTACH\n");
break;
case DLL_THREAD_ATTACH:
printf("DllMain, DLL_THREAD_ATTACH\n");
break;
case DLL_THREAD_DETACH:
printf("DllMain, DLL_THREAD_DETACH\n");
break;
case DLL_PROCESS_DETACH:
printf("DllMain, DLL_PROCESS_DETACH\n");
break;
default:
printf("DllMain, ????\n");
break;
}
return TRUE;
}
#else
CP_BEGIN_EXTERN_C
__attribute__((constructor))
/**
* initializer of the dylib.
*/
static void Initializer(int argc, char** argv, char** envp)
{
printf("DllInitializer\n");
}
__attribute__((destructor))
/**
* It is called when dylib is being unloaded.
*
*/
static void Finalizer()
{
printf("DllFinalizer\n");
}
CP_END_EXTERN_C
#endif
输出不同: 在Windows上 可执行主,加载库 DLL Moo,构造函数 DllMain,DLL_PROCESS_ATTACH 可执行主,释放库 DllMain,DLL_PROCESS_DETACH DLL Moo,析构函数 可执行主,退出
<强>的Linux 强> 可执行主,加载库 DllInitializer DLL Moo,构造函数 可执行主,释放库 DllFinalizer DLL Moo,析构函数 可执行主,退出
在Windows上,Moo构造函数在DLLMain之前被调用,而在linux上,它是在使用属性((构造函数))定义的初始化程序之后调用的。
为什么?