Linkerfehler LNK2005 und LNK1169
-
Hallo.
Ich wage mich an ein etwas größes Projekt. Jedoch ist mir nun direkt am Anfang ein Linkerfehler aufgetreten.//main.cpp #include "solarCoordinates.h" int main (char argc, char * argv[]) { int returnOfOFD = _CSC.GetOpenFileDialog(); return 0; }//solarCoordinates.h #ifndef _solarCoordinateTransformation_h_ #define _solarCoordinateTransformation_h_ #include <string> class solarCoordinateTransformation { public: int GetOpenFileDialog(); private: std::string PathOfTheRoundupFile; } _CSC; //HIER MEINE ICH #endif// solarCoordinates.cpp #include "solarCoordinates.h" #include <Windows.h> int solarCoordinateTransformation::GetOpenFileDialog() { OPENFILENAME ofn; char path[1000]; HWND hWnd = GetConsoleWindow(); ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hWnd; ofn.lpstrFile = path; ofn.lpstrFile[0] = '\0'; ofn.nMaxFile = sizeof(path); ofn.lpstrFilter = "Textdatei (*.txt)\0*.TXT\0"; ofn.nFilterIndex = 1; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = "Z:"; ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; BOOL successfulDialogBox = GetOpenFileName(&ofn); if (successfulDialogBox == 1) { int returnFromMesasgeBox = MessageBox(hWnd,"Bitte wählen Sie eine Datei aus.","Datei einlesen fehlgeschlagen!",MB_OKCANCEL|MB_ICONWARNING); if (returnFromMesasgeBox == 1) { _CSC.GetOpenFileDialog(); return 0; } else { return -1; } } _CSC.PathOfTheRoundupFile = path; return 0; }Meine Frage ist, ob ich der Klasse, so wie ich es gemacht habe einen "Standardnamen" zu geben. Markiert in der Headerdatei.
2. Frage ist, warum diese Fehler auftreten.
1>solarCoordinates.obj : error LNK2005: "class solarCoordinateTransformation _CSC" (?_CSC@@3VsolarCoordinateTransformation@@A) ist bereits in main.obj definiert.1>D:\Eigene Datein\Dropbox\rechner 2.1.1\Debug\rechner 2.1.1.exe : fatal error LNK1169: Mindestens ein mehrfach definiertes Symbol gefunden.Hat hier jemand eine Antwort?
-
Nun der Linker hat natürlich Recht, deine Variable _CSC ist in jeder Übersetzungseinheit definiert, in der dein Header eingebunden wird. Man macht keine Definitionen in Headern.
Daher drei Gegenfragen:
1. Ist dir klar, dassclass foo { /* ... */ } bar;eine Variable Namens bar vom Typ foo definiert (nicht deklariert!)?
2. Ist dir klar, was der Unterschied zwischen Deklaration und Definition ist?
3. Falls du beide Fragen mit "Ja" beantworten konntest: Was wolltest du damit erreichen?P.S.: Noch so eine Sache: Der Bezeichner _CSC ist in doppeltem Sinne für die Implementierung reserviert. Du solltest ihn ändern. Reservierte Bezeichner sind:
Reserved in any scope, including for use as implementation macros:
In jedem Gültigkeitsbereich:
- Bezeichner mit Unterstrich gefolgt von einem Großbuchstaben am Anfang (z.B. _CSC)
- Bezeichner mit doppeltem Unterstrich, egal wo
Im globalen Gültigkeitsbereich:
- Bezeichner mit Unterstrich am Anfang (z.B. dein globales _CSC)
-
Ok danke. Ich kann dir das mit ja beantworten.
Ich wollte damit erreichen, dass ich die private Variable innerhalb der Klasse benutzen kann, da ich die Klasse auch mal innerhald der Klasse aufrufe und sie halt jedes mal neu initialisieren muss. Dadurch bekomm ich dann werte wie 9,0000000E10 doer so.
Ggf. Löse ich es anders und rufe sie dann in der main hintereinander auf. Mal schaun.
-
Crysis_02 schrieb:
Ich wollte damit erreichen, dass ich die private Variable innerhalb der Klasse benutzen kann, da ich die Klasse auch mal innerhald der Klasse aufrufe und sie halt jedes mal neu initialisieren muss. Dadurch bekomm ich dann werte wie 9,0000000E10 doer so.
Ich verstehe nicht, was du meinst. Dir scheint irgendwie nicht klar zu sein, was Klassen und Objekte sind und wie sie sich zueinander verhalten.
-
Eigentlich schon.
-
In solarCoordinates.h wird eine Variable namens _CSC definiert. solarCoordinates.h wird sowohl von main.cpp als auch von solarCoordinates.cpp #included, daher gibt es _CSC zwei mal. Das verwirrt den Linker und wahrscheinlich wolltest du nur ein einziges _CSC.
Lösung://solarCoordinates.h #ifndef _solarCoordinateTransformation_h_ #define _solarCoordinateTransformation_h_ #include <string> class solarCoordinateTransformation { public: int GetOpenFileDialog(); private: std::string PathOfTheRoundupFile; };// _CSC; //HIER MEINE ICH extern solarCoordinateTransformation _CSC; #endifJetzt gibt es keine Variable _CSC mehr innerhalb von solarCoordinates.h, aber solarCoordinates.h behauptet, dass es irgendwo sowas gibt. Wenn du jetzt kompilierst sagt dir der Linker, dass er Objekt _CSC nicht finden kann.
// solarCoordinates.cpp #include "solarCoordinates.h" #include <Windows.h> //Kram solarCoordinateTransformation _CSC;Jetzt gibt es _CSC wieder, genau ein Mal und sowohl solarCoordinates.cpp als auch main.cpp benutzen das.
-
Bei der Gelegenheit möchte ich auch noch "static initialization order fiasco" erwähnen, was einem bekannt sein sollte, wenn man globale Objekte (statischer Speicher) anlegt, die dynamisch initialisiert werden.