Windows Vs上的DLL Main. __attribute __((constructor))Linux上的入口点 [英] DLL Main on Windows Vs. __attribute__((constructor)) entry points on Linux

查看:293
本文介绍了Windows Vs上的DLL Main. __attribute __((constructor))Linux上的入口点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑代码

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之后调用.

On windows, Moo constructor is called before DLLMain and whereas on linux it is called after Initializer defined using attribute((constructor)).

为什么?

推荐答案

Moo构造函数在之前 DllMain之前不被称为,而在 from DllMain中被称为.确切地说,它是从真正的DllMain中调用的,Windows首先调用该函数.这个真实的DllMain调用C ++构造函数,然后调用您的C ++ DllMain.真正的DllMain的原因恰好是初始化构造函数,这在C之前是不需要的

Moo constructor isn't called before DllMain, it is called from DllMain. To be precise, its called from the real DllMain, the function Windows calls first. This real DllMain calls C++ constructors and then calls your C++ DllMain. The reason for this real DllMain is exactly to initialize constructors, something which wasn't needed in C before

Linux(GCC/ELF)根本没有这个概念.它只有构造函数.您的手动ctor和Moo的C ++ ctor对待方式相同.

Linux (GCC/ELF) doesn't have this concept at all; it only has constructors. Your manual ctor and the C++ ctor for Moo are treated the same.

这篇关于Windows Vs上的DLL Main. __attribute __((constructor))Linux上的入口点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆