(Dateien nach einer bestimmten Reihenfolge kompilieren) Linker-Fehler
-
Hallo,
ich habe ein Frage, und zwar ob es in VS2008 die Möglichkeit gibt, die Dateien nach einer Reihenfolge zu kompilieren. Ich habe schon danach gesucht, hab aber nichts gefunden.
Hoffe auf eine schnelle Antwort
MFG
DieTuer
-
denke nicht, aber wozu soll das gut sein?
-
1.Datei
//ieInitWindow.h //Initialisieren des Fensters #pragma once //Funktionen LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); ieResult InitWindow(int iWidth, int iHeight, char* cName, HICON hIcon); ieResult ExitWindow(); ieResult MessageLoop(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
2.Datei
//IEngine.h //Funktion: Headerdatei der Engine #pragma once #include <Math.h> ... #include <Windows.h> [...] 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"
Wenn jetzt die 1.Datei vor der 2. kompeliert wird, sind die ganzen Funktionen und Variablen nicht definiert
-
Na und? Das Linken geschieht später, dann wenn alles bereits compiliert ist.
-
Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (auch C++0x) in das Forum Compiler- und IDE-Forum verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Nur so nebenbei: Den Vorgang nennt man "Kompilierung".
-
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_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?