none
DLL Singleton? RRS feed

  • Frage

  • Hallo zusammen!

    Momentan "zerpflücke" ich gerade meine Anwendung. Es sind einzelne Teile momentan nach dem Alexander Andrescu Singleton Muster aufgebaut. Diese Komponenten sollen auch weiterhin nur einmal in der Anwendung vorhanden sein, aber die selben Instanzen sollen nur einmal pro Prozess vorhanden sein. Andere Komponenten (welche DLLs sind) sollen auch auf diese Instanzen zugreifen können. Hierzu habe ich jetzt den folgenden Ansatz gefunden:

    class MyInterface
    {
     virtual void Do() = 0;
    };

    Die DLL Main sieht so aus:
    BOOL APIENTRY DllMain( HMODULE hModule,
                           DWORD  ul_reason_for_call,
                           LPVOID lpReserved
          )
    {
     switch (ul_reason_for_call)
     {
     case DLL_PROCESS_ATTACH:
      // create instance of our singleton
      extern void CreateInstance(void); // Funktion innerhalb dieser DLL
      CreateInstance();
      break;
     case DLL_THREAD_ATTACH:
     case DLL_THREAD_DETACH:
      break;
     case DLL_PROCESS_DETACH:
      // destroy instance of our singleton
      extern void DestroyInstance(void); // Funktion innerhalb dieser DLL
      DestroyInstance();
      break;
     }
     return TRUE;
    }

    Create/DestroyInstance(void) erstellt/zerstört einen Pointer auf eine Implementierung, welche dann via "GetInterface" an die "externe" Anwendung übergeben wird. Also ähnlich wie COM.
    Wird jetzt diese DLL noch von einer anderen DLL im selbem Prozess geladen, gibt es dann auch auch nur "diese eine Instanz"? Mein Gedanke ist, dass diese DLL ja nur einmal pro Prozess im Speicher sein kann, ergo nur eine Instanz erstellt sein kann. Ist das wahr oder habe ich einen Denkfehler drin?

    Gruß

    Georg

     

    Donnerstag, 24. März 2011 13:18

Antworten

  • Eine "normale" DLL (kein WinSxS, keine speziellen Manifeste) wird immer nur einmal in den Prozess geladen. Ein static ist damit zugleich ein prozessweites Sngleton...


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    • Als Antwort markiert schorsch_76 Donnerstag, 24. März 2011 21:05
    Donnerstag, 24. März 2011 18:30
    Moderator

Alle Antworten

  • 1. Eine DLL gibt es immer nur einmal im Prozess.

    2. Die muss klar sein, dass bestimmte Aufrufe von Funktionen in der DllMain untersagt sind.

    3. Du magst ein Problem bekommen, wenn DLL-1 etwas aus DLL-2 benutzt und DLL-2 etwas aus DLL-1, die Reihenfolge wie Deine Instanzen erzeugt werden ist dann zufällig.

    4. Welches Methode für Singletonsmeinst Du? So etwas?

    template <class T>
    class Singleton{
    public:  
    static T& instance()  
      {   
        static T singleton;   
        return singleton;  
      }
    private:  
      Singleton() {} // Disallow construction of Singleton<T> instances
    };
    

    Ich halte es immer noch für besser, dass das singleton erst erzeugt wird, wenn es benutzt wird. Das hat vor allem bei vielen DLLs den Vorteil, dass Du sicher sein kannst, dass alle DLLs auch wirklich initialisiert sind.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Donnerstag, 24. März 2011 14:48
    Moderator
  • Hallo Martin,

    ich habe ein Singleton template mit Lifetime, construction, Threading Policies.

    Bisher habe ich das "Reihenfolge der Zerstörung" Problem über eine Policy namens "SingletonWithLongevity" gelöst. Jedes Singleton, hat eine Nummer welche die Reihenfolge der Zerstörung bei "atexit" vorgibt. In einer statischen Anwendung ist das einfach super.

    Das verzögerte erzeugen bei Verwendung lässt sich natürlich in der GetInterface() Funktion lösen.

    Das Buch, auf dem dieses Singleton bisher basierte, ist "Modernes C++ Design" [1]

    Da es diese DLL ja nur einmal im Prozess geben kann, kann ich also davon ausgehen, dass es nur eine Instanz gibt. Über die Reihenfolge der Erzeugung/Zerstörung muss ich mir dann noch Gedanken machen.

    Danke dir Martin :-)

    Gruß

    Georg

    [1] http://www.amazon.de/Modern-Generic-Programming-Patterns-Applied/dp/0201704315/ref=sr_1_1?ie=UTF8&s=books-intl-de&qid=1300978926&sr=1-1

    Donnerstag, 24. März 2011 15:06
  • Eine "normale" DLL (kein WinSxS, keine speziellen Manifeste) wird immer nur einmal in den Prozess geladen. Ein static ist damit zugleich ein prozessweites Sngleton...


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    • Als Antwort markiert schorsch_76 Donnerstag, 24. März 2011 21:05
    Donnerstag, 24. März 2011 18:30
    Moderator