(Dateien nach einer bestimmten Reihenfolge kompilieren) Linker-Fehler



  • Der spuckt noch vor dem Linken die Fehler aus



  • Achso, das meinst du - dafür gibt es eine recht einfache Lösung: du schreibst deine Include-Anweisungen so, daß jeder die von ihm verwendeten Deklarationen erhält.



  • Also das ich bei ieInitWindow.h #include "IEngine.h" schreibe? Oder wie ist das gemeint?



  • Ja, und umgekehrt sind die #include's am Ende der IEngine.h vermutlich unnötig.



  • Dann kommen aber diese Fehler:

    1>Verknüpfen...
    1>IEngine.obj : error LNK2005: "__int64 ie_g_llFrequency" (?ie_g_llFrequency@@3_JA) ist bereits in ieInitWindow.obj definiert.
    1>IEngine.obj : error LNK2005: "int ie_g_bExitCalled" (?ie_g_bExitCalled@@3HA) ist bereits in ieInitWindow.obj definiert.
    1>IEngine.obj : error LNK2005: "int ie_g_bActivated" (?ie_g_bActivated@@3HA) ist bereits in ieInitWindow.obj definiert.
    1>IEngine.obj : error LNK2005: "double ie_g_dFrequency" (?ie_g_dFrequency@@3NA) ist bereits in ieInitWindow.obj definiert.
    1>IEngine.obj : error LNK2005: "double ie_g_dTime" (?ie_g_dTime@@3NA) ist bereits in ieInitWindow.obj definiert.
    1>IEngine.obj : error LNK2005: "struct HWND__ * ie_g_hWnd" (?ie_g_hWnd@@3PAUHWND__@@A) ist bereits in ieInitWindow.obj definiert.
    1>IEngine.obj : error LNK2005: "double ie_g_dNumSecsPassed" (?ie_g_dNumSecsPassed@@3NA) ist bereits in ieInitWindow.obj definiert.
    1>IEngine.obj : error LNK2005: "int ie_g_bInitCalled" (?ie_g_bInitCalled@@3HA) ist bereits in ieInitWindow.obj definiert.
    


  • Das sind alles Veriablen, die ich in IEngine.h definiert habe.



  • In einem Header definiert man ja auch keine Variablen - dort solltest du bestenfalls extern-Deklarationen verwenden (und deinem Projekt eine IEngine.cpp mit den Definitionen hinzufügen).



  • Das ist IEngine.h:

    //IEngine.h
    //Funktion:	Headerdatei der Engine	
    #pragma once
    
    #include <Windows.h>
    ...
    
    //Globale Variablen
     BOOL		ie_g_bInitCalled;		// Wurde die Engine initialisiert?
     BOOL		ie_g_bExitCalled;		// Wurde die Engine heruntergefahren?
     LONGLONG	ie_g_llFrequency;		// Frequenz des Zeitgebers
     double		ie_g_dFrequency;		// Frequenz des Zeitgebers (double)
     double		ie_g_dTime;				// Zeitzähler
     double		ie_g_dNumSecsPassed;	// Vergangene Sekunden seit letztem Frame
     BOOL		ie_g_bActivated;		// Ist das Fenster aktiv?
    ...
    
    //Rückgabewerte
    enum ieResult
    {
    	IE_OK			=	0,
    	IE_ERROR		=	1,
    	IE_CANCELED		=	2,
    	IE_NOT_FOUND	=	3,
    	IE_STOP			=	4,
    };
    
    //Die einzelnen Bestandteile hinzufügen
    #include "ieInitWindow.h"
    #include "ieVector3.h"
    #include "ieMatrix.h"
    ...
    

    Was habe ich jetzt falsch gemacht?



  • Dieser Header wird von mehreren Übersetzungseinheiten verwendet - da bekommt jede eine Kopie der definierten Variablen (und der Linker reagiert mit dem obengenannten Fehler). Das Zauberwort hier heißt "extern":

    //IEngine.h
    ...
    extern BOOL        ie_g_bInitCalled;        // Wurde die Engine initialisiert?
    ...
    
    //IEngine.cpp
    #include "IEngine.h"
    
    BOOL        ie_g_bInitCalled;        // Wurde die Engine initialisiert?
    ...
    


  • Bau mal Codeguards in deine Header.

    Header am Ende nicht gut, hat man schon geschrieben 😕

    MfG f.-th.



  • Vielen Dank! es klappt wieder! 😉



  • Hatte das falsche Stichwort 😡

    Das war gemeint:
    http://de.wikibooks.org/wiki/C-Programmierung:_Eigene_Header

    MfG f.-th.



  • f.-th. schrieb:

    Bau mal Codeguards in deine Header.

    Die Tuer schrieb:

    #pragma once

    Er braucht also keine (sofern er den Code nicht durch Compiler, die diese Direktive nicht unterstützen, jagen möchte).



  • Wenn ich jetzt aber in ein anderes Projekt das Engine-Projekt hinzufüge, kommen Linker-Fehler (Verweis auf nicht aufgelöstes externes Symbol ""enum ieResult __cdecl InitWindow(int,int,char *,struct HICON__ *,struct HINSTANCE__ *)" (?InitWindow@@YA?AW4ieResult@@HHPADPAUHICON__@@PAUHINSTANCE__@@@Z)" in Funktion "_WinMain@16 ...)

    IEngine.h

    ...
    #include"ieInitWindow.h"
    

    ieInitWindow.h

    #pragma once
    #include "IEngine.h"
    
    //Funktionen
    LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
    ieResult InitWindow(int iWidth, int iHeight, char* cName, HICON hIcon, HINSTANCE hInst);
    

    ieInitWindow.cpp

    #include "ieInitWindow.h"
    ieResult InitWindow(int iWidth, int iHeight, char *cName, HICON hIcon, HINSTANCE hInst)
    {
    	[Definition der Funktion]
    }
    

    Test-Projekt
    Test.cpp

    #include "..\\..\\Engine\\Engine\\IEngine.h"
    
    int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int ncmdshow)
    {
    	InitWindow(10, 10, "Name", NULL, hInst);
    	...
    
    }
    


  • Kann mir denn wirklich keiner helfen? 😞



  • Hast du denn deinem Projekt die "Engine.lib" hinzugefügt (ich nehme mal an, du hast eine statische bzw. dynamische Library erstellt)?

    Wenn nicht, dann mußt du auch noch die Engine-Sourcen deinem Projekt hinzufügen...

    P.S: "..\..\\Engine\\Engine\\IEngine.h" solltest du nicht verwenden, sondern in deinem Projekt den Pfad auf die Header-Dateien mitgeben (damit du nur noch "Engine\\IEngine.h" [bzw. noch besser "Engine/IEngine.h"] schreiben mußt).



  • Ich habe keine library erstellt 🙄 Wozu ist das denn nötig und wie mache ich das?
    (ich hab noch nie Libraries erstellt)



  • Was für einen Projekttyp hast du denn bei deinem Engine-Projekt eingestellt?

    Bzgl. Library, s. http://de.wikipedia.org/wiki/Programmbibliothek



  • Als Projekttyp habe ich Win32-Projekt eingestellt.



  • Hallo Florian,

    ich nehme mal an, daß du das Engine-Projekt nicht als eigenständige Anwendung laufen lassen möchtest? Dann wähle unter "Allgemein"/"Konfigurationstyp" bei den Projektoptionen "statische Bibliothek" (oder alternativ "dynamische Bobliothek", falls du eine DLL erstellen willst) aus.

    Nun kannst du bei deinem anderen Projekt diese als Library eintragen (unter "Linker"/"Eingabe"/"Zusätzliche Abhängigkeiten"): Engine.lib
    Du mußt dann noch den Suchpfad dazu eintragen: "Linker"/"Allgemein"/"Zusätzliche Bibliotheksverzeichnisse".

    Eine andere Alternative besteht darin, in einer "Solution" beide Projekte zu verwalten und eine Referenz (Verweis) auf das Engine-Projekt in dem anderen Projekt hinzuzufügen.

    P.S. evtl. solltest du deine vorherigen Beiträge mal editieren, damit man deinen Namen nicht mehr sieht...


Anmelden zum Antworten