c++ - Windows 上的 DLL Main 对比。 __attribute__((constructor)) Linux 上的入口点

标签 c++ linux windows shared-libraries dllmain

考虑代码

执行文件:

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;
}

动态链接库

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

输出不同:

在 window 上

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 上,它在使用属性((构造函数))定义的 Initializer 之后调用。

为什么?

最佳答案

Moo 构造函数不是之前 DllMain 调用的,而是来自 DllMain 调用的。准确地说,它是从真正的DllMain中调用的,Windows首先调用的函数。这个真正的 DllMain 调用 C++ 构造函数,然后调用您的 C++ DllMain。这个真正的 DllMain 的原因正是为了初始化构造函数,这是以前 C 中不需要的东西

Linux(GCC/ELF)根本没有这个概念;它只有构造函数。您的手动构造函数和 Moo 的 C++ 构造函数被同等对待。

关于c++ - Windows 上的 DLL Main 对比。 __attribute__((constructor)) Linux 上的入口点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22763945/

相关文章:

linux - 使用 awk 将登录统计信息打印到文件

wpf - WPF 是我应用程序的安全选择吗?

windows - 使用已登录用户的用户名在 Windows 登录上获取邮件

c# - Windows 窗体计算 C#

c++ - InterlockedIncrement 用法

c++ - 视频节目中更好的边缘滤波算法

Linux One Liner 返回 eth 名称、ip、ma​​c 和子网

c++ - sizeof(...) = 0 或 C++ 模板中的条件变量声明

c++ - TBB_tbb_LIBRARY_DEBUG-未找到

linux - 我如何在主机提供期间在容器内执行命令