1

私の質問はこれとまったく同じではありません(これは理論的なものではありません。メッセージ ループのないメイン スレッドしかなく、InitInstance と ExitInstance は適切な呼び出しではありません)。

メッセージ ループのないコンソール アプリを使用しています。このアプリは、エクスポートされた関数を使用できるように、LoadLibrary 関数を使用して exe を読み込みます。悪いニュース: exe の DllMain 関数が呼び出されません (また、def ファイルを使用してシンボル テーブルを確認したところ、DllMain は正しく表示されます)。ドキュメントは、ロードされたモジュールがDLLの場合に呼び出されると述べています(残念です)。

LoadLibrary が呼び出されたとき (そして、FreeLibrary が呼び出されたとき) に exe の DllMain 関数が実行される可能性がある条件 (存在する場合) は何ですか?

よろしくお願いします

4

4 に答える 4

4

最も明白な条件は、LoadLibrary() を呼び出すプロセスが明示的に GetProcAddress("DllMain") を取得してから呼び出すことです。

于 2009-01-16T15:34:45.200 に答える
3

条件は次のとおりです。

1) ロードされるバイナリは DLL としてコンパイルされました (gcc/ld を使用--sharedする場合、オプションを使用することを意味します。使用する場合--shared、結果のファイルは dll になり、実行されません。以下を参照してください)。

2)IMAGE_FILE_DLLロードされるバイナリ ファイルの PE ファイル ヘッダーに設定されます。設定されている場合、ファイルは dll であり、Windows リンカーは、このファイルをプログラムにリンクするときにその関数を呼び出します (実行時またはコンパイル時DllMain()のリンク方法は関係ありません)。そのためには、ファイルも (1) を満たす必要があります。ただし、このフラグを使用すると、ロードされるバイナリ ファイルは実行できなくなります。が設定されていない場合、ファイルがプログラムにロードされたときに呼び出されません。LoadLibrary()-llibrarynameIMAGE_FILE_DLLDllMain()

dll をコンパイルしてヘッダーから--shared手動で削除するIMAGE_FILE_DLL(つまり、16 進エディターを使用する) ことはできません。実行すると、DllMain()実行されるだけで、fdwReason定義されていない数値になります (0x28ffd4私のマシンでは)。

アップデート

Windows 上のすべての DLL および EXE ファイルは PE ファイルです。違いは、リンク方法と、ヘッダーに設定されているフラグです。それが私が書く理由file being loadedであり、ではありませんdll being loaded

最後の段落では、ファイルを dll としてコンパイルし、ヘッダーを変更して exe に変換するシナリオについても説明しています。うまくいきません。

命名はそれとは何の関係もありません (任意の名前を選択できます。いくつかのpexports+dlltoolいじくり回しで、.exe ファイルのインポート ライブラリを作成し、それを次のようにリンクできます。-lexenamewithoutextension

明確にするために:

  • なしでコンパイルした場合--shared
    • IMAGE_FILE_DLL設定されず、実行可能になりますが、リンク時に DllMain() は呼び出されません。
  • でコンパイルした場合--shared
    • IMAGE_FILE_DLLその中に設定され、実行可能ではありませんが、リンクすると DllMain() が呼び出されます。
  • なしでコンパイルする場合は、フラグを手動で --sharedオンにします。IMAGE_FILE_DLL
    • もう実行できなくなり、リンクしても DllMain() は呼び出されません。
  • でコンパイルする場合は、フラグを手動で --sharedオフにします。IMAGE_FILE_DLL
    • 実行可能になりますが、main() の代わりに DllMain() が実行され、リンク時に DllMain() は呼び出されません。
于 2012-09-13T01:52:51.357 に答える
1

実際、関数の「DllMain」という名前は、Windows によって完全に無視されます (Windows NT 3.x の古い Windows API ドキュメントでは、これが明示的に述べられています)。

DLL がロードされると、関数 DllMain() ではなく、ファイルのエントリ ポイントにある関数が呼び出されます。

もちろん、リンカーは DllMain() がこの関数であるという方法で DLL ファイルを作成します。

ただし、EXE ファイルの場合、エントリ関数 (WinMain() を呼び出す) はエントリ ポイントにあります。

したがって、EXE ファイルを DLL としてロードする場合、Windows がこの関数を呼び出せないことは明らかです。

于 2013-08-21T20:41:54.640 に答える
0

MSaltersの良い答えを完成させる:

そのため、LoadLibrary の直後に DLL_XXX_ATTACH を指定して「偽の」DllMain を呼び出し、FreeLibrary の直前に DLL_XXX_DETACH を指定して、手動で他の呼び出しを行います。

次の別の実装は、偽の DllMain で EXE を自動的にコールバックできるインターフェイス DLL をビルドしてロードすることです (動作するかどうかはわかりません)。ただし、多くの場合、偽の DllMain を手動で呼び出すよりも複雑になる場合があります。(DllMain で LoadLibrary を実行できません)

于 2009-01-16T17:11:32.947 に答える