考虑代码
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上
Executable Main, loading library
DLL Moo, constructor
DllMain, DLL_PROCESS_ATTACH
Executable Main, Freeing library
DllMain, DLL_PROCESS_DETACH
DLL Moo, destructor
Executable Main, exiting
Linux
Executable Main, loading library
DllInitializer
DLL Moo, constructor
Executable Main, Freeing library
DllFinalizer
DLL Moo, destructor
Executable Main, exiting
在Windows上,Moo构造函数在DLLMain之前调用,而在Linux上,它在使用attribute((constructor))定义的Initializer之后调用。
为什么?
最佳答案
Moo构造函数没有在DllMain
之前调用,而是从DllMain
调用。确切地说,它是从真正的DllMain
调用的,Windows首先调用该函数。这个真正的DllMain
调用C++构造函数,然后调用您的C++ DllMain
。使用真正的DllMain
的原因恰好是初始化构造函数,这在C之前是不需要的
Linux(GCC/ELF)根本没有这个概念。它只有构造函数。您的手动ctor和Moo的C++ ctor的处理方式相同。
关于c++ - Windows Vs上的DLL Main。 __attribute __((constructor))Linux上的入口点,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22763945/