(Dateien nach einer bestimmten Reihenfolge kompilieren) Linker-Fehler
-
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_HeaderMfG 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...
-
Danke für die Antwort und den Tipp
(habe ganz vergessen meinen Namen herauszukürzen
)