Problem mit extern



  • Ich bekomme mein Programm nicht zum Laufen. Verwende ich "extern" falsch?
    Ich kann leider nicht so viel mit den Fehlermeldungen anfangen.

    1>P1Map.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: int __thiscall P1Player::GetY(void)" (?GetY@P1Player@@QAEHXZ)" in Funktion ""public: void __thiscall P1TileMap::Draw(void)" (?Draw@P1TileMap@@QAEXXZ)".
    1>P1Map.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: int __thiscall P1Player::GetX(void)" (?GetX@P1Player@@QAEHXZ)" in Funktion ""public: void __thiscall P1TileMap::Draw(void)" (?Draw@P1TileMap@@QAEXXZ)".
    1>P1WinMain.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: __thiscall P1Game::P1Game(void)" (??0P1Game@@QAE@XZ)" in Funktion ""void __cdecl `dynamic initializer for 'Game''(void)" (??__EGame@@YAXXZ)".
    1>P1WinMain.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: __thiscall P1Game::~P1Game(void)" (??1P1Game@@QAE@XZ)" in Funktion ""void __cdecl `dynamic atexit destructor for 'Game''(void)" (??__FGame@@YAXXZ)".
    

    P1Include.h:

    #include <windows.h>
    
    // Konstanten & Methoden
    #include "P1Constants.h"
    #include "P1Methods.h"
    
    // DirectX
    #pragma comment (lib, "d3d9.lib")
    #include <d3d9.h>
    
    // Klassen
    #include "P1Graphics.h"
    #include "P1Game.h"
    #include "P1Map.h"
    #include "P1Player.h"
    
    // Global verfügbar machen
    extern P1Game   Game;
    extern P1Player Player;
    

    P1WinMain.h:

    #include "P1Include.h"
    
    P1Game Game;
    P1Player Player;
    
    int CALLBACK WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR lpCmdLine,
                         int nCmdShow) 
    {
    
      return 0;
    }
    

    P1Map.cpp:

    #include "P1Include.h"
    
    void P1TileMap::Draw() 
    {
      int iPlrViewX = BoundBy(Player.GetX() - iViewWidth / 2, 0, iMapWidth - iViewWidth);
      int iPlrViewY = BoundBy(Player.GetY() - iViewHeight / 2, 0, iMapHeight - iViewHeight);
    
      for(int iY = iPlrViewX - iPlrViewX % iTileHeight; iY < iMapHeight; iY += iTileHeight) {
        for(int iX = iPlrViewY - iPlrViewY % iTileWidth; iX < iMapWidth; iX += iTileWidth) {
          P1Tile Tile = GetTile(iX, iY);
          // TODO: Tile zeichnen
        }
      }
    }
    

    P1Player.h:

    class P1Player
    {
      private:
        int iX, iY;
    
      public:
        P1Player();
        P1Player(int, int);
        ~P1Player();
    
      public:
        int GetX();
        int GetY();
    };
    

    P1Player.cpp

    #include "P1Include.h"
    
    /* -- Konstruktoren und Destruktoren -- */
    P1Player::P1Player() {}
    P1Player::P1Player(int iParX, int iParY) : iX(iParX), iY(iParY) {}
    P1Player::~P1Player() {}
    
    /* -- Methoden -- */
    inline int P1Player::GetX() 
    {
      return iX;
    }
    
    inline int P1Player::GetY() 
    {
      return iY;
    }
    


  • Mit "extern" haben Deine Fehler nicht viel zu tun.

    Es werden folgende fehlende Definitionen angemeckert:

    public: int P1Player::GetY(void)
    public: int P1Player::GetX(void)
    public: P1Game::P1Game(void)
    public: P1Game::~P1Game(void)
    

    Die Definition der letzten beiden Funktionen kann ich nirgends wo sehen. Aber die ersten beiden wurden in P1Player.cpp definiert. Der Fehler ist hier, dass Du "inline" falsch benutzt hast. Denn die Funktion ist sonst nirgends wo als Inline-Funktion deklariert, nur in dieser einen Übersetzungseinheit. Das ist nicht erlaubt. Wenn das eine inline-Funktion sein soll, muss sie auch dementsprechend in anderen ÜEs als solche deklariert werden. Und wenn in einer ÜE eine Funktion als inline-Funktion deklariert ist und benutzt wird, muss auch eine Definition in derselben ÜE vorhanden sein. So will es die "ODR" (one definition rule). Praktisch heißt das, dass Du sie im Header als inline-Funktion definieren oder das inline-Schlüsselwort bei der Definition in der einen cpp-Datei entfernen musst.

    kk



  • Danke schonmal für die Antwort. Wenn ich inline entferne, dann funktioniert mein Code. Aber ich würde gerne inline verwenden. Wie stelle ich das an?

    Langt es, wenn ich vor der Methode in der Header Datei inline schreibe?



  • Tappich schrieb:

    Aber ich würde gerne inline verwenden. Wie stelle ich das an?
    Langt es, wenn ich vor der Methode in der Header Datei inline schreibe?

    Habe ich alles schon beantwortet:

    krümelkacker schrieb:

    ... Wenn das eine inline-Funktion sein soll, muss sie auch dementsprechend in anderen ÜEs als solche deklariert werden. Und wenn in einer ÜE eine Funktion als inline-Funktion deklariert ist und benutzt wird, muss auch eine Definition in derselben ÜE vorhanden sein. So will es die "ODR" (one definition rule). Praktisch heißt das, dass Du sie im Header als inline-Funktion definieren oder das inline-Schlüsselwort bei der Definition in der einen cpp-Datei entfernen musst.

    Aber vielleicht ist Dir etwas von der Terminologie nicht ganz klar. Also:

    void foo();    // <-- reine [b]Deklaration[/b]
    void foo() {}  // <--       [b]Definition[/b] (gleichzeitig Deklaration)
    

    ÜE = Übersetzungeinheit = das, was der Präprozessor ausgehend von einer cpp-Datei (mit allen "Includes" (rekursiv) und Makro-Ersetzungen) dem eigentlichen Compiler zum Fraß vorwirft.

    kk



  • Okay, dann wäre alles geklärt. Danke Dir krümelkacker 🙂


Anmelden zum Antworten