C DLL导出函数调用两次

C DLL导出函数调用两次,c,dll,C,Dll,我制作了一个短DLL,当进程加载它时,它将显示一个MessageBox。但是,消息框会显示两次。看来DLL导出函数调用了两次。您能看看我的代码中是否有需要修改的内容,以便MessageBox只显示一次吗 #include <windows.h> #include <stdio.h> __declspec(dllexport) void sampledllmain() { MessageBox(NULL, "sample text","sample title",

我制作了一个短DLL,当进程加载它时,它将显示一个MessageBox。但是,消息框会显示两次。看来DLL导出函数调用了两次。您能看看我的代码中是否有需要修改的内容,以便MessageBox只显示一次吗

#include <windows.h>
#include <stdio.h>

__declspec(dllexport) void sampledllmain()
{
    MessageBox(NULL, "sample text","sample title", 0);
}

BOOL APIENTRY DllMain(HANDLE hHandle, DWORD dwReason, LPVOID Reserved)
{
    switch(dwReason)
    {
        case DLL_PROCESS_ATTACH:
                sampledllmain();
                break;
    }
    return 1;
}
如报告所述:

  • 它通过
    LoadLibrary()
    加载指定的DLL
  • 它通过
    GetProcAddress()
    获取函数的地址
  • 它调用函数,传递命令行尾部,该尾部是
  • 就你而言:

  • 调用时,它会调用,在您的情况下,
    DllMain
    调用
    sampledllmain
  • 获取
    sampledllmain
  • 调用
    sampledllmain
    (第二次)
  • 要解决您的问题,请执行以下操作:

    • 添加第二个函数
      虚拟
      (例如)
    • 在命令行上使用
      rundll32“DLL路径”,dummy
    另外,你还可以调试你的dll

    MessageBox
    调用
    dllMain

    #include <windows.h>
    __declspec(dllexport) void sample(void)
    {
        MessageBox(NULL, "sample text test", "sample title test", 0);
    }
    BOOL APIENTRY DllMain( HMODULE hModule,
                           DWORD  ul_reason_for_call,
                           LPVOID lpReserved
                         )
    {
        switch (ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
            MessageBox(NULL, "attach", "DllMain", 0);
            break;
        case DLL_THREAD_ATTACH:
            break;
        case DLL_THREAD_DETACH:
            break;
        case DLL_PROCESS_DETACH:
            MessageBox(NULL, "detach", "DllMain", 0);
            break;
        }
        return TRUE;
    }
    
    #包括
    __declspec(dllexport)无效样本(无效)
    {
    MessageBox(空,“样本文本测试”,“样本标题测试”,0);
    }
    BOOL APICENT DllMain(模块HMODULE,
    德沃德·乌尔打电话的理由,
    LPVOID lpReserved
    )
    {
    开关(ul\u呼叫原因\u)
    {
    案例DLL\u进程\u附加:
    消息框(空,“附加”,“DllMain”,0);
    打破
    案例DLL\u线程\u连接:
    打破
    案例DLL\u线程\u分离:
    打破
    案例DLL\u进程\u分离:
    消息框(空,“分离”,“DllMain”,0);
    打破
    }
    返回TRUE;
    }
    
    使用
    rundll32.exe lib.dll运行,示例如下所述:

  • 它通过
    LoadLibrary()
    加载指定的DLL
  • 它通过
    GetProcAddress()
    获取函数的地址
  • 它调用函数,传递命令行尾部,该尾部是
  • 就你而言:

  • 调用时,它会调用,在您的情况下,
    DllMain
    调用
    sampledllmain
  • 获取
    sampledllmain
  • 调用
    sampledllmain
    (第二次)
  • 要解决您的问题,请执行以下操作:

    • 添加第二个函数
      虚拟
      (例如)
    • 在命令行上使用
      rundll32“DLL路径”,dummy
    另外,你还可以调试你的dll

    MessageBox
    调用
    dllMain

    #include <windows.h>
    __declspec(dllexport) void sample(void)
    {
        MessageBox(NULL, "sample text test", "sample title test", 0);
    }
    BOOL APIENTRY DllMain( HMODULE hModule,
                           DWORD  ul_reason_for_call,
                           LPVOID lpReserved
                         )
    {
        switch (ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
            MessageBox(NULL, "attach", "DllMain", 0);
            break;
        case DLL_THREAD_ATTACH:
            break;
        case DLL_THREAD_DETACH:
            break;
        case DLL_PROCESS_DETACH:
            MessageBox(NULL, "detach", "DllMain", 0);
            break;
        }
        return TRUE;
    }
    
    #包括
    __declspec(dllexport)无效样本(无效)
    {
    MessageBox(空,“样本文本测试”,“样本标题测试”,0);
    }
    BOOL APICENT DllMain(模块HMODULE,
    德沃德·乌尔打电话的理由,
    LPVOID lpReserved
    )
    {
    开关(ul\u呼叫原因\u)
    {
    案例DLL\u进程\u附加:
    消息框(空,“附加”,“DllMain”,0);
    打破
    案例DLL\u线程\u连接:
    打破
    案例DLL\u线程\u分离:
    打破
    案例DLL\u进程\u分离:
    消息框(空,“分离”,“DllMain”,0);
    打破
    }
    返回TRUE;
    }
    

    使用
    rundll32.exe lib.dll运行,sample

    您的调用正在使用
    DllMain
    调用
    sampledllmain
    ,使用
    rundll32
    调用,请为您的测试添加第二个伪函数,这样您就可以使用
    rundll32“dll路径”,伪函数,当然它会被调用两次。从
    DllMain
    中删除
    sampledllmain
    。您的调用是使用
    DllMain
    调用
    sampledllmain
    ,使用
    rundll32
    调用,请为您的测试添加第二个虚拟函数,这样您就可以使用
    rundll32“DLL路径”,虚拟的
    ,当然它会被调用两次。从
    DllMain
    中删除
    sampledllmain
    。我希望在进程加载DLL时显示消息框。但是当我直接在DllMain函数中调用MessageBox时,它被调用了4次。我在某个地方读到,我们应该为它创建一个不同的导出函数,并根据类似于DLL\u PROCESS\u ATTACH的条件从DLL main调用它。那么,如何在调用DllMain()时显示消息框呢?但是为什么要用
    rundll32.exe
    (将其作为参数传递)再次调用它呢?我使用rundll32仅用于测试。如何在加载DLL时仅执行一次MessageBox函数?使用LoadLibrary()加载DLL时,会自动调用DllMain()函数。所以,理想情况下,如果我直接在MessageBox的DllMain()中调用,那么它应该只执行MessageBox()一次,对吗?为什么会发生两次或更多次呢?你可以自己测试一下。你不能添加另一个函数,用rundll32代替
    sampledllmain
    调用它吗?我猜你对消息框的多次调用与对
    DllMain
    的不同调用有关,调用的
    dwReason
    我希望在进程加载DLL时显示消息框。但是当我直接在DllMain函数中调用MessageBox时,它被调用了4次。我在某个地方读到,我们应该为它创建一个不同的导出函数,并根据类似于DLL\u PROCESS\u ATTACH的条件从DLL main调用它。那么,如何在调用DllMain()时显示消息框呢?但是为什么要用
    rundll32.exe
    (将其作为参数传递)再次调用它呢?我使用rundll32仅用于测试。如何在加载DLL时仅执行一次MessageBox函数?使用LoadLibrary()加载DLL时,会自动调用DllMain()函数。所以,理想情况下,如果我直接在MessageBox的DllMain()中调用,那么它应该只执行MessageBox()一次,对吗?为什么?