2012-04-30 39 views
9

私はDelphiで書いたDLLを扱うのに多くの問題があります。私は図書館に次のコードを使用してDllMain関数を設定しました:DLL_PROCESS_ATTACHの前にDelphi DllMain DLL_PROCESS_DETACHが呼び出されました。

begin 
    DllProc := DllMain; 
end. 

DllMain手順は、次のようになります。私は見つけることだ何

procedure DllMain(reason: Integer); 
begin 
    if reason = DLL_PROCESS_DETACH then 
    OutputDebugString('DLL PROCESS DETACH') 
    else if reason = DLL_PROCESS_ATTACH then 
    OutputDebugString('DLL PROCESS ATTACH') 
    else if reason = DLL_THREAD_ATTACH then 
    OutputDebugString('DLL THREAD ATTACH') 
    else if reason = DLL_THREAD_DETACH then 
    OutputDebugString('DLL THREAD DETACH') 
    else 
    OutputDebugString('DllMain'); 
end; 

(DETACHが呼ばれるように思われることですATTACHが呼び出される前に、私がコントロールしていない)呼び出し元によって、2回(?それは可能ですか、あるいは私はこれがどのように機能するはずか誤解していますか?私の期待は、ATTACHのすべてのコールが一致するDETACHコールで満たされるということですが、それはそうではないようです。

ここには何がありますか?

答えて

12

残念ながら、beginがdllコードで実行された場合、OSは既にライブラリ内でDllMainを呼び出しています。したがって、あなたのDllProc := DllMain;ステートメントが実行されると、それはすでに遅すぎます。 Delphiコンパイラは、dllがプロセスにアタッチされているときにユーザーコードを実行することを許可していません。解決策として(あなたがこの問題を回避することを呼び出すことができる場合)は、単位initalizationセクションにまたはライブラリのコードで独自のDllMain機能を自分で呼び出すことです:

begin 
    DllProc := DllMain; 
    DllMain(DLL_PROCESS_ATTACH); 
end; 

relevant documentation

:DLLの初期化コードがプロシージャを呼び出し、DLL_PROCESS_ATTACHをパラメータとして指定した場合にのみ、DLL_PROCESS_ATTACHがプロシージャに渡されます。私が見つけてる何

+0

ええと...私はこれが私の問題すべてに対する解決策になることを期待していましたが、この追加の知識は(私の質問には真実ですが)まだ私の問題を解決していません。私は別の質問:)を作成する必要がありますように見えます。ご協力いただきありがとうございます! – aardvarkk

+0

あなたは何を理解していません。この質問のすべてがここにあります。コードが実行される前に発生するDllMainの唯一の呼び出しは 'DLL_PROCESS_ATTACH'です。だから、あなたはちょうどSertacが言うようにそれを書いて、それはすべていいです。 –

+0

いいえ、これは完全にはっきりしています。私はそれを理解し、それを実装することができます。しかし、私のより大きな問題(これに関係していたと思っていた)に対する答えは、実際にはこの問題に関連していないことが明らかになりました。検索が続行されます! – aardvarkk

-1

は、これまでと呼ばれる接続する前にDETACHは(私がコントロールしていないこと)、呼び出し元で(?!2回)と呼ばれているように見えるということです。

Petzoldの「Programming Windows 5th edition」によると、
DLL_PROCESS_ATTACHは、アプリケーションが起動すると呼び出され、
DLL_THREAD_ATTACHは、添付されたアプリケーション内の新しいスレッドが開始されると呼び出されます。
DLL_PROCESS_DETACHは、アプリケーションに接続されたアプリケーションが終了すると呼び出されます。
DLL_THREAD_DETACHは、添付アプリケーション内のスレッドが終了すると呼び出されます。

DLL_THREAD_DETACHは、先にDLL_THREAD_ATTACHに対応することなく呼び出すことができます。
これは、スレッドがDLLにリンクしているアプリケーションに対してより先にを起動したときに発生します。
これは、アプリケーションがコンパイル時に静的にリンクするのではなく、LoadLibraryを使用してDLLを手動でロードするときに主に発生します。

+0

私は分かりません。プロセスのないスレッドを意味しますか?そして 'LoadLibrary'は 'DLL_PROCESS_ATTACH'につながりませんか? –

+0

これは 'DLL_PROCESS_DETACH'が何度も起こっている理由を説明していないようです。 –

関連する問題