Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

04.11.2009, 22:28

Problem mit "Singleton"-Klasse in DLL

Moinsen,
ich versuche gerade meine kleine Engine in eine DLL umzuschreiben. Dabei definiere ich eine globale Instanz einer Klasse innerhalb der DLL nach dem folgenden Prinzip:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/////////////////////////////////////////////////

//  app_dll.h


class __declspec(dllexport) cApp
{
      static cApp* m_pInst;
      int m_value;
public:
      cApp(const int& val);
      ~cApp();

      static cApp* getInst()
      {
             return m_pInst;
      }

      void showValue();
};

// Globale Instanz der Klasse cApp, die in der DLL 

// und in der Anwendung Zugriff auf Funkionen der Klasse gewährt

inline cApp* GlobalInst()
{
      return cApp::getInst();
}




/////////////////////////////////////////////////

//  app_dll.cpp


cApp* cApp::m_pInst = NULL;

cApp::cApp(const int& val)
{
      m_value = val;
      m_pInst = this;
}

cApp::~cApp()
{
      m_pInst = NULL;
}

void cApp::showValue()
{
      // irgendeine Ausgabe von m_value

     std::cout << this->m_value << "\n";
}




/////////////////////////////////////////////////

//  main.cpp   der Testanwendung


//...


int main()
{
     //...


     new cApp(123);                  // Initialisieren von GlobalInst()

     GlobalInst()->showValue(); // Ausgabe von m_value

     delete GlobalInst();            // Instanz wieder freigeben


     // ...

}


Das Erstellen der DLL klappt soweit ohne Probleme, aber beim Ausführen der Testanwendung scheitert das Ganze am Aufruf von this->m_value innerhalb von showValue().
Wenn ich jedoch den Konstruktor der Klasse und showValue() innerhalb der Header app_dll.h definiere, funktioniert das Programm tadellos. Mein Problem ist also, dass ich die Definitionen nicht in die .cpp-Datei ausgelagert bekomme.

Die Fehlermeldung, die ich bekomme, sagt übrigens folgendes:

Zitat


Unbehandelte Ausnahme bei 0x0041146b in test.exe: 0xC0000005: Zugriffsverletzung beim Schreiben an Position 0x00000008.


Ich vermute, dass der Zeiger m_pInst irgendwie "verloren" geht, dadurch dass der in app_dll.cpp stehende Code immer dynamisch der Test-Anwendung zugefügt wird (im Gegensatz zum Code aus der app_dll.h).

Ich hoffe ihr könnt mir helfen, google konnte es diesmal jedenfalls nicht :)

MfG

edit: Quelltext korrigiert

2

05.11.2009, 01:53

Also,

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/////////////////////////////////////////////////

//  app_dll.h

class __declspec(dllexport) cApp
{
private:
      static cApp* m_pInst;
      cApp(){}
      ~cApp() { if(m_pInst) destroy();} }
      int m_value;
public:
      void init(const int& val);
      void destroy();
      static cApp* getInst();
      void showValue();
};

/////////////////////////////////////////////////

//  app_dll.cpp

void cApp::init(const int& val)
{
    m_value = val;
}

cApp* cApp::getInstance()
{
    if( !m_pInst)
      m_pInst= new cApp();
    return m_pInst;
}
 
void cApp::destroy()
{
    // static

    if (m_pInst)
    {
      delete m_pInst;
    }
}

void cApp::showValue()
{
      // irgendeine Ausgabe von m_value

     std::cout << m_value << "\n";
}

/////////////////////////////////////////////////

//  main.cpp   der Testanwendung

int main()
{
     cApp* app= cApp::getInst();
     app->init(123);                  // Initialisieren

     app->showValue();      // Ausgabe von m_value

     app->destroy()           // zerstören

}


so ungefähr müsste es gehen.

:arrow: Konstruktor muss 'private' sein! (damit man nicht mehrere Instanzen erzeugen kann)

3

05.11.2009, 23:11

Jo, vielen Dank. Jetzt funzt es :D
Die Definition von getInst() muss auch in app_dll.cpp stehen, damit es korrekt läuft. Mich würde mal interessieren, warum.

Kann es sein, dass wenn Konstruktor/init() und getInst() in der Header stehen, m_pInst eine Adresse im Speicherbereich der Anwendung zugeteilt wird? Und andersrum, wenn sie in der .cpp-Datei stehen, m_pInst eine Adresse im Speicherbereich der DLL bekommt?

MfG

Werbeanzeige