MFC Extension Dlls



  • Hallo!

    **1.)**Meine Anwendung nutzt u.a. eine MFC erweiterungs Dll (dll_1), in der "angepasste" MFC-Klassen sind.

    Diese Erweiterungs Dll wird aber auch von anderen "normalen" MFC Dlls genutzt, die auch wiederum von meiner Anwendung genutzt werden.

    Nun steht ja in der DllMain-Funktion einer MFC Erweiterungs Dll folgender Kommentar:

    // Insert this DLL into the resource chain
    		// NOTE: If this Extension DLL is being implicitly linked to by
    		//  an MFC Regular DLL (such as an ActiveX Control)
    		//  instead of an MFC application, then you will want to
    		//  remove this line from DllMain and put it in a separate
    		//  function exported from this Extension DLL.  The Regular DLL
    		//  that uses this Extension DLL should then explicitly call that
    		//  function to initialize this Extension DLL.  Otherwise,
    		//  the CDynLinkLibrary object will not be attached to the
    		//  Regular DLL's resource chain, and serious problems will
    		//  result.
    

    Hießt das jetzt, dass ich die Code-Zeile(n)

    new CDynLinkLibrary(MyExtensionsDLL);
    // bzw.
    AfxTermExtensionModule(MyExtensionsDLL);
    

    in eine Methode exportieren muss, die explizit von der EXE aufgerufen wird, damit es keine Probleme mit den anderen Dlls gibt, oder wie ist das gemeint?

    2.)
    Meine dll_1 ist zudem abhängig von einer weiteren Dll, die ebenfalls MFC-Klassen ableiten, jedoch von keinem anderem Projekt (exe/dll) sonst genutzt wird. Muss diese Dll dann auch eine erweiterungs Dll sein?


  • Mod

    Also, das ist etwas kompliziert.

    1. Eine EXE hat ein CWinApp Objekt und dieses einen Modulestate in dem alle extension DLLs verzeichnet werden.
    2. Eine Regular DLL hat auch ein CWinApp Objekt und dieses einen Modulestate in dem alle extension DLLs verzeichnet werden.
    3. Eine Extension DLL hat genau solch einen Modulestate nicht aber wird beim laden in den aktuellen Modulestate geladen und dort registriert.

    Dieser Modulestate verwaltet nun auch eine Resource-Chain und auch Ketten wie Objekte gefunden werden etc.

    A. Wird eine Extension DLL implizit von der EXE geladen steht sie im Mopdulestate der EXE
    B. Wird die Extension DLL implizit von einer Regular DLL geladen und ist zuvor noch nicht von der EXE geladen), dann steht sie im Modulestate der DLL.
    C. Wird die Extension DLL implizit von einer Regular DLL geladen und ist zuvor noch nicht von der EXE auch schon geladen, dann steht sie im Modulestate der EXE, aber nichtin der der DLL ⚠ ⚠ ⚠

    Klar? Auf diesen kritischen Fall C bezieht sich IMHO dieser Text!

    HTH



  • Hallo Martin!

    Martin Richter schrieb:

    Klar? Auf diesen kritischen Fall C bezieht sich IMHO

    🙂 Noch nicht so ganz.

    Ich versuche nochmal die aktuelle Situation zu verdeutlichen, um sicherzugehen, dass wir uns (eher ich Dich) richtig verstehen. Das Projekt sieht wie folgt aus:
    app.exe
    regular-mfc.dll
    ext-mfc-1.dll
    ext-mfc-2.dll

    App.exe hat ist abhängig von regular-mfc.dll und ext-mfc-1.dll.
    Regular-mfc.dll ist abhängig von ext-mfc-1.dll.
    Ext-mfc-1.dll ist abhängig von ext-mfc-2.dll.

    Ich denke - nach mehrmahligem Lesen - das hier Fall C zutrifft (wie Du bereits erwähnt hast). Dennoch bin ich etwas verunischert ob ich jetzt die Default-MFC-Extension-DllMain-Funkion nutzen kann oder ob ich das Erstellen des CDynLinkLibrary-Objekts in eine exportierte Funktion auslagern muss, die dann in CWinApp-Klasse von app.exe und regular-mfc.dll aufgerufen werden.


  • Mod

    Das Problem ist, dass Du nicht weißt in welcher Reihenfolge die DLLs initialisiert werden, also die DLLMains aufgerufen werden. Und Du benötigst die Registrierung in beiden Ketten.



  • Martin Richter schrieb:

    Das Problem ist, dass Du nicht weißt in welcher Reihenfolge die DLLs initialisiert werden, also die DLLMains aufgerufen werden. Und Du benötigst die Registrierung in beiden Ketten.

    Hmm, also geht nur der Weg über die exportierte Funktion und deren Aufruf in den CWinApp::InitInstance Methoden. richtig?


  • Mod

    Jupp. Das sehe ich auch so.

    Es kann nur gehen, wenn beide CWinApp die Extension DLL in Ihrer Liste der Module haben.



  • Martin Richter schrieb:

    Jupp. Das sehe ich auch so.

    Es kann nur gehen, wenn beide CWinApp die Extension DLL in Ihrer Liste der Module haben.

    Super und danke.

    Den Terminierungszweig der Erweiterungs-Dlls habe ich so gelassen, damit das Objekt wieder zerstört wird. (Der Debugger kommt in den Dlls genau 1-mal vorbei).

    else if (dwReason == DLL_PROCESS_DETACH)
    {
        TRACE0("MyExtensions.DLL Terminating!\n");
    
       // Terminate the library before destructors are called
       AfxTermExtensionModule(MyExtensionsDLL);
    }
    

  • Mod

    Das ist auch OK, aber das Du implizit lädst kann die DLL nur bei Prozessende entladen werden und da spielt es keine Rolle mehr.


Log in to reply