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

jojendersie

Frischling

  • »jojendersie« ist der Autor dieses Themas

Beiträge: 47

Wohnort: Berlin

  • Private Nachricht senden

1

22.11.2007, 14:51

virtuelle Funktion kann nicht aufgerufen werden

Ich habe folgende Basisklasse in einer DLL (in der Headerdatei):

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
class ORKTECK_API OrGUI
{
protected:
    ...
public:
    virtual OrResult Render()   {OR_ERROR("Aufruf einer abstrakten Funktion.", OR_ERROR);}
    virtual OrResult ProcessInput(DWORD dwParam)    {OR_ERROR("Aufruf einer abstrakten Funktion.", OR_ERROR);}
    virtual OrResult Init(char* pctex1, char* pctex2, const float x, const float y, const float w, const float h, const BOOL bCanFocus = TRUE)  {OR_ERROR("Aufruf einer abstrakten Funktion.", OR_ERROR);}
        ...


und vererbe diese:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
class ORKTECK_API OrGUIProcessBar: public OrGUI
{
private:
    ...
public:

    OrResult Render();
    OrResult ProcessInput(DWORD dwParam);
    OrResult Init(char* pctex1, char* pctex2, const float x, const float y, const float w, const float h, const BOOL bCanFocus = TRUE);
    ...
};


Die Methoden sind dann in einer cpp Datei deklariert
(OrResult OrGUIProcessBar::Render() {...})

Wenn ich nun eine der Methoden aufrufe, egal ob mit Zeigern auf die Basisklasse oder Kindklasse, kommt es zu einer Zugriffsverletzung, dabei wird offensichtlich die Funktion nicht gefunden, da diese niemals betreten werden. Nehme ich das virtual weg kann ich die Funktion aufrufen, aber natürlich nur wenn ich den Typ auch kenne.
Das passiert auch, wenn die virtuellen Funktionen abstrakt sind.
(In der TribaseEngine-GUI funktioniert eine solcher Vererbung aber anscheinend.)

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

2

22.11.2007, 15:51

Zeig mal den betreffenden Codeteil!
@D13_Dreinig

jojendersie

Frischling

  • »jojendersie« ist der Autor dieses Themas

Beiträge: 47

Wohnort: Berlin

  • Private Nachricht senden

3

22.11.2007, 16:41

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    OrGUIProcessBar* pProcessBar;
    m_HUD.Init("Textures\\BG_LOAD.tga");

    // Prozessanzeige erstellen

    pProcessBar = (OrGUIProcessBar*)(m_HUD.AddObject(OR_GUI_PROCESSBAR));
    pProcessBar->Init("Textures\\BG_LOAD_EPRO.tga",
                      "Textures\\BG_LOAD_FPRO.tga",
                      0.43f,
                      0.8f,
                      0.4f,
                      0.0625f,
                      FALSE);
    pProcessBar->SetMaxPercentage(g_BgGame.GetLoadingMaxPointer());
    pProcessBar->SetPercentage(g_BgGame.GetLoadingCountPointer());


Die Methoden SetMaxPercentage und SetPercentage lassen sich problemlos aufrufen, das Objekt existiert mit sicherheit

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

4

22.11.2007, 17:11

Was macht m_HUD.AddObject?
@D13_Dreinig

jojendersie

Frischling

  • »jojendersie« ist der Autor dieses Themas

Beiträge: 47

Wohnort: Berlin

  • Private Nachricht senden

5

22.11.2007, 17:30

Na in das HUD eine Instanz des angegebenen typs einfügen, das Objekt existiert danach definitif.

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

6

22.11.2007, 17:37

Zitat von »"jojendersie"«

Na in das HUD eine Instanz des angegebenen typs einfügen, das Objekt existiert danach definitif.


Achwas? :shock: Ich würde das gern in Form vom Code sehen! ;)
@D13_Dreinig

jojendersie

Frischling

  • »jojendersie« ist der Autor dieses Themas

Beiträge: 47

Wohnort: Berlin

  • Private Nachricht senden

7

22.11.2007, 17:44

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
// ******************************************************************

// Fügt ein neues Objekt auf die Oberfläche und gibt einen Pointer darauf zurück

OrGUI* OrHUD::AddObject(DWORD dwType)
{
    OrGUI* pObject;
    switch(dwType)
    {
    case OR_GUI_BUTTON:
        pObject = (OrGUI*)(OrMemAlloc(sizeof(OrGUIButton)));
        break;
    case OR_GUI_TEXTFIELD:
        pObject = (OrGUI*)(OrMemAlloc(sizeof(OrGUITextField)));
        break;
    case OR_GUI_SLIDER:
        pObject = (OrGUI*)(OrMemAlloc(sizeof(OrGUISlider)));
        break;
    case OR_GUI_FRAME:
        pObject = (OrGUI*)(OrMemAlloc(sizeof(OrGUIFrame)));
        break;
    case OR_GUI_CHECKBOX:
        pObject = (OrGUI*)(OrMemAlloc(sizeof(OrGUICheckBox)));
        break;
    case OR_GUI_PROCESSBAR:
        pObject = (OrGUI*)(OrMemAlloc(sizeof(OrGUIProcessBar)));
        break;
    case OR_GUI_IMAGE:
        pObject = (OrGUI*)(OrMemAlloc(sizeof(OrGUIImage)));
        break;
    case OR_GUI_LIST:
        pObject = (OrGUI*)(OrMemAlloc(sizeof(OrGUIList)));
        break;
    }
    ObjectList.AddEntry(&pObject);
    pObject->SetFocus(FALSE);

    return pObject;
}

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

8

22.11.2007, 17:58

Keine Ahnung was OrMemAlloc genau macht, aber es sieht so aus als würde kein korrektes Objekt erzeugt werden (soll in dem Fall heißen der vptr ist nicht korrekt initialisiert), also kann das natürlich garnicht funktionieren.

Wie wärs denn einfach mit pObject = new OrGUIButton();?
@D13_Dreinig

jojendersie

Frischling

  • »jojendersie« ist der Autor dieses Themas

Beiträge: 47

Wohnort: Berlin

  • Private Nachricht senden

9

22.11.2007, 18:20

Ich will hier nicht für doof verkauft werden, aber ich sagte das Objekt ist korrekt, das ergeben debug und andere tests, außerdem erzeuge ich noch an hunderten anderen Stetllen Objekte die auch alle richtig funktionieren. Außerdem funktioniert je auch bei diesem Objekt alles, wenn ich in der Basisklasse das Schlüsselwort virtual wegnehme. Mein Problem ist, dass das nicht funktionirt wenn es virtuel ist!!!

rewb0rn

Supermoderator

Beiträge: 2 773

Wohnort: Berlin

Beruf: Indie Game Dev

  • Private Nachricht senden

10

22.11.2007, 19:18

Benutzt du im Konstruktor der Klassen die Funktion ZeroMemory? Die überschreibt nämlich auch den gesamten vtable.

Werbeanzeige