2012-04-30 6 views
9

Ich habe eine Menge Probleme mit einer DLL, die ich in Delphi geschrieben habe. Ich habe eine Funktion DllMain mit dem folgenden Code in der Bibliothek einzurichten:Delphi DllMain DLL_PROCESS_DETACH vor DLL_PROCESS_ATTACH aufgerufen

begin 
    DllProc := DllMain; 
end. 

Mein DllMain Verfahren sieht wie folgt aus:

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; 

Was ich Befund bin ist, dass DETACH genannt zu werden scheint (zweimal von einem Anrufer (den ich nicht kontrolliere), bevor ATTACH überhaupt angerufen wird. Ist das überhaupt möglich oder missverstehe ich, wie das funktionieren soll? Meine Erwartung wäre, dass jeder ATTACH-Aufruf mit einem passenden DETACH-Aufruf beantwortet würde, aber das scheint nicht der Fall zu sein.

Was geht hier los ?!

Antwort

12

Leider, wenn begin in Ihrem DLL-Code ausgeführt wird, hat das OS bereits DllMain in Ihrer Bibliothek aufgerufen. Wenn Ihre DllProc := DllMain; Anweisung ausgeführt wird, ist es bereits zu spät. Der Delphi-Compiler lässt nicht zu, dass Benutzercode ausgeführt wird, wenn die DLL an einen Prozess angehängt ist. Die vorgeschlagene Abhilfe (wenn man rufen, dass eine Abhilfe) ist Ihre eigene DllMain Funktion selbst in einer Einheit initialisiert Abschnitt oder in der Bibliothek Code aufzurufen:

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

Die relevant documentation:

Hinweis : DLL_PROCESS_ATTACH wird nur dann an die Prozedur übergeben, wenn der Initialisierungscode der DLL die Prozedur aufruft und DLL_PROCESS_ATTACH als Parameter angibt.

+0

Hmm ... Ich hatte gehofft, dass dies die Lösung für all meine Probleme sein würde, aber dieses zusätzliche Wissen (obwohl es wahr ist und meine Frage beantwortet) hat meine Probleme noch nicht behoben. Sieht so aus, als müsste ich eine andere Frage stellen :). Danke für Ihre Hilfe! – aardvarkk

+0

Was verstehst du nicht? Es ist alles hier in dieser Frage richtig. Der einzige Aufruf von DllMain, der auftritt, bevor Ihr Code ausgeführt werden kann, ist für 'DLL_PROCESS_ATTACH'. Du schreibst es einfach so, wie Sertac sagt, und alles ist gut. –

+0

Nein, das ist völlig klar. Ich verstehe es und könnte es umsetzen. Es hat jedoch gezeigt, dass die Antwort auf mein größeres Problem (von dem ich hoffte, dass es damit zusammenhängt), in Wirklichkeit nicht mit diesem Problem zusammenhängt. So geht die Suche weiter! – aardvarkk

-1

Was ich finde, ist, dass DETACH genannt zu werden scheint (zweimal ?!) von einem Anrufer (die ich nicht kontrollieren), bevor ATTACH jemals genannt wird.

Laut "Programmierung Windows 5th Edition" von Petzold.
DLL_PROCESS_ATTACH wird aufgerufen, wenn die Anwendung startet und
DLL_THREAD_ATTACH wenn ein neuer Thread in einer angefügten Anwendung gestartet wird.
DLL_PROCESS_DETACH wird aufgerufen, wenn eine mit Ihrer Anwendung verknüpfte Anwendung beendet wird.
DLL_THREAD_DETACH wird aufgerufen, wenn ein Thread in einer angehängten Anwendung beendet wird.

Beachten Sie, dass es möglich ist, dass DLL_THREAD_DETACH ohne eine entsprechende frühere DLL_THREAD_ATTACH aufgerufen werden kann.
Dies tritt auf, wenn der Thread vorher zu der Anwendung gestartet wurde, die mit der DLL verknüpft.
Dies tritt hauptsächlich auf, wenn eine Anwendung die DLL manuell mithilfe von LoadLibrary lädt, anstatt zur Kompilierungszeit statisch zu verknüpfen.

+0

Ich verstehe nicht. Meinst du einen Thread ohne Prozess? Und 'LoadLibrary' führt nicht zu einem 'DLL_PROCESS_ATTACH'? –

+0

Dies scheint nicht zu erklären, warum 'DLL_PROCESS_DETACH' mehrfach vorkommt. –

Verwandte Themen