2016-09-07 25 views
0

プロセスによってロードされたときにMessageBoxを表示する短いDLLを作成しました。ただし、メッセージボックスが2回表示されます。 DLLエクスポート関数が2回呼び出されるようです。 MessageBoxが一度しか表示されないように、コード内で変更が必要なものがあるかどうか確認してください。DLLエクスポート関数が2回呼び出されました

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

Iは、以下に示すようにRundll32の使用DLLをロード:

rundll32 "path to DLL",sampledllmain 
+0

で、あなたのテストのための第2のダミー関数を追加してください' rundll32 "DLLへのパス"、dummy' – dvhh

+2

もちろん、2回呼び出されます。 'sampledllmain'を' DllMain'から削除してください。 – Ari0nhh

答えて

2

information page about rundll32.exeによって記載されるように:

  1. それはLoadLibrary()を介して指定されたDLLをロードします。
  2. GetProcAddress()で関数のアドレスを取得します。
  3. コマンドラインのテールを渡して関数を呼び出します。あなたのケースでは

LoadLibrary()は、それがsampledllmainを呼び出しDllMainあなたのケースでは、DllMain呼び出し、呼び出された

  1. アドレスsampledllmain
  2. を取得します。sampledllmain(2回目)。あなたの問題を解決する

  • (例えば)第二の機能dummyを追加
  • コマンドラインで使用rundll32 "path to DLL",dummy

PS:あなたはできる追加のノートでもそこにあなたのDLLをデバッグguides that describe how to do it

あなたが使用できるように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; 
} 

実行して、呼び出しがsampledllmain` DllMain` `として` rundll32`呼び出しに `呼んでいるrundll32.exe lib.dll,sample

+0

プロセスによってDLLが読み込まれると、MessageBoxが表示されます。しかし、私がMessageBoxにDllMain関数を直接呼び出すと、それは4回呼び出されます。私は、別のエクスポート関数を作成し、DLL_PROCESS_ATTACHのような条件に基づいてDLLメインから呼び出さなければならないと読んだところです。では、DllMain()の呼び出しでメッセージボックスを表示するにはどうすればよいですか? –

+0

しかし、 'rundll32.exe'(パラメータとして渡す)を使って2回目にそれを呼び出すのはなぜですか? – dvhh

+0

私はrundll32をテストのためだけに使います。 DLLがロードされたときにMessageBox関数を一度だけ実行する方法はありますか? LoadLibrary()を使用してDLLをロードすると、DllMain()関数が自動的に呼び出されます。ですから、理想的には、MessageBoxのDllMain()内に直接コールを置くと、MessageBox()が1回だけ実行されるはずです。なぜそれが2回以上起こるのでしょうか?これを自分でテストすることができます。 –

関連する問題