Statische globale Variable in DLLs



  • Hallo Community,

    ich beschäftige mich gerade mit statischen Variablen in dll's.
    Dabei hab ich ein Testprogramm in welchem ich in einem namespace eine statische Variable erstellen möchte.

    // Vorrausdeklaration von meineKlasse
    class meineKlasse;
    // Vector für die Liste Objecten
    typedef std::vector<meineKlasse*> objectStore;
    
    namespace staticVars
    {
    	// statische Liste
    	namespace objMeinKlasse	
    	{
    		static objectStore* DSI_Liste = 0; // <-- Hier Problem
    	};
    };
    

    Jetzt habe ich dabei festgestellt diese 'DSI_Liste' nur in der DLL-Klasse existiert in welcher ich Sie erstelle. Bei mir hier in einer statischen Funktion welche folgenden Code ausführt:

    //... mache Dinge
            if (insert)
    	{
    		staticVars::objMeinKlasse::DSI_Liste->push_back(this);
    	}
    //... mache Dinge
    

    Jetzt habe ich natürlich das Problem das ich wenn ich von anderer Stelle aus auf meine 'DSI_Liste' zugreiffen will (aus einer andern Klasse(DLL)) diese natürlich nicht initalisiert ist und ich folglich eine Zugriffsverletzung bekomme.

    Habe dann versucht die 'DSI_Liste' 'extern' zu deklarieren oder mit WXEXPORT(=__declspec(dllexport)) zu exportieren. Was aber daran scheiterte das das Schlüsselwort 'static' fehlt und beim einbinden des Headers in dem der 'namespace' und die Variable deklariert wird ich die LNK Fehlermeldung bekomme das diese bereits definiert ist.

    Auf der Web-Site
    "How do I share data in my DLL with an application or with other DLLs?"
    http://msdn.microsoft.com/en-us/library/h90dkhs0(VS.80).aspx
    habe ich dann erfahren das man diese so initalisieren soll(muss) um sie in anderen DLL's zu nutzen und habe meinen Code wie folgt geändert

    // Vorrausdeklaration von meineKlasse
    class meineKlasse;
    // Vector für die Liste Objecten
    typedef std::vector<meineKlasse*> objectStore;
    
    namespace staticVars
    {
    	// statische Liste
    	namespace objMeinKlasse	
    	{
    #pragma data_seg(".shared")
    		static objectStore* DSI_Liste = 0; // <-- Hier Problem
    #pragma data_seg()
    #pragma comment(linker, "/SELECTION:shared,RWS")
    	};
    };
    

    Was mir folgende Fehlermeldungen einbrachte:

    nmpDataSet.obj : warning LNK4229: Ungültige /SELECTION:shared,RWS-Direktive gefunden; wird ignoriert.
    1>DataSet_bool.obj : warning LNK4229: Ungültige /SELECTION:shared,RWS-Direktive gefunden; wird ignoriert.
    1>DataSetInterpreter.obj : warning LNK4229: Ungültige /SELECTION:shared,RWS-Direktive gefunden; wird ignoriert.
    1>DataSetInterpreter_bool.obj : warning LNK4229: Ungültige /SELECTION:shared,RWS-Direktive gefunden; wird ignoriert.
    1>   Bibliothek "'Path-To_Lib*'.lib" und Objekt "'Path*'.exp" werden erstellt.
    

    Was mach ich falsch, oder was fehlt noch. Oder gibt es noch andere Möglichkeiten wie ich in DLL's einen im 'namespace' erstellten 'statische Vector' erzeugen kann, auf welchen ich von allen DLL's aus zugreifen kann.

    Bin über jede Anregung dankbar, besten Dank in vorraus..

    Ollow



  • Warum wird das Wort 'v o r r a u s' herrausgenommen !?

    Ja also die Fehlermeldungen war ein Tippfehler

    #pragma comment(linker, "/SECTION:.shared,RWS")
    

    sollte es heißen.

    Allerdings bleiben die Probleme die gleichen. 😞



  • Im Header:

    extern objectStore *DSI_Liste;
    

    In einer Übersetzungseinheit:

    objectStore *DSI_Liste = 0;
    

    ...allerdings sind globale Variablen, ganz besonders in Bibliotheken eine problematische Angelegenheit. Spätestens, wenn da mal einer Multithreading mit betreiben will, fliegt dir das ganze böse auseinander.

    Wahrscheinlich solltest du dein Design nochmal überdenken. Was genau hast du eigentlich vor?



  • Warum möchtest Du die Variable sharen... mach doch ein Interface!



  • Willst Du auf den inhalt der statischen globalen variable von mehreren Prozessen zugreifen oder soll nur jeder prozess der die dll lädt seine eigene statische globale variable haben ?

    grüße



  • Ollow_AM schrieb:

    Warum wird das Wort 'v o r r a u s' herrausgenommen !?

    Weil es sich "Voraus" schreibt. Es gibt noch ein paar solcher Filter, zum Beispiel für "Standard" mit zwei t.



  • @seldon. Da habe ich 'voraus' aber schon oft falsch geschriebel 😉 *lach*

    Hmm, naja das mit 'extern' will er nicht weil er mir sagt das Object ist schon definiert, wenn er den Header einließt.

    Was ich genau machen will. Grob gesagt habe ich eine dataSet Klasse in der ich alle Standardtypen(int, double etc.) verwalte und speichern kann. Natürlich soll dies auch für eigene Klassen funktionieren. Desshalb habe ich eine Abstrakte 'Save' Klasse welche mir die Daten der Klasse in einen String wandelt(oder ließt) und ich habe dafür 'Interpreter' die mir einen String prüfen. Dafür habe ich ich abstrakte Interpreter-Klasse als Mutter und eben die Kinder (z.B. Interpreter_bool).
    Die Interpreter die in der Anwendung erlaubt oder genutzt werden, sind in der statischen Liste hinterlegt. Hoffe ich konnte mich jetzt einigermaßen klar ausdrücken.

    @theta. Wie soll ich das Interface verstehen ?? Das ich die Liste per Funktionsaufruf zurück bekomme? Brauch die Liste statisch, damit ich die Objecte die darin sind nicht mehrfach erzeugen muss.

    @zeusosc. Ja genau das ist das Problem, das ich nicht von allen Dll's aus zugreifen kann. Also ich will von allen Kind-Objecten der 'Interpreter'-Klasse aus, und bis jetzt halt von von meiner 'dataSet' Klasse (s. seldon's Erklärung) zugreifen können (ggf. kommen da auch noch andere dazu)

    Grüße...



  • Nun gut ich habe mich jetzt doch dazu entschieden meine Struktur zu verändern.

    Vielen Dank erstmal....



  • welchen Compiler nutzt du?

    mfg



  • Ich benutze den Microsoft Visuall Studio 2008, Prof. Edition. 🙂


Anmelden zum Antworten