Problem mit doppelten Definitionen trotz #ifndef bzw. #pragma once
-
Hallo allerseits!
Ich wollte mein Projekt ein bisschen aufräumen und aus einer .cpp Datei zwei .cpp Dateien und einen Header .h machen.
[In der einen .cpp Datei werden Funktionen implementiert, in der anderen aufgerufen.]
Dieser Header muss dann natürlich in beiden .cpp Dateien eingebunden werden.
Und das bereitet wohl Probleme:
Beim Linken bekomme ich error, die z.B. so aussehen:
Linking...
3dfunctions.obj : error LNK2005: "struct IDirect3D9 * g_pD3D" (?g_pD3D@@3PAUIDirect3D9@@A) already defined in mfc-testDlg.objund noch ein paar weitere "already defined" Meldungen.
Ich vermute, es liegt an der zweifachen Verwendung des Headers:
Entferne ich den include dieses Headers aus einer der beiden .cpp Dateien, taucht dieser Error nicht mehr auf (dafür natürlich viele andere...).Doppelte Definitionen wollte ich dabei eigentlich durch die übliche Header-Klammer vermeiden:
#ifndef _THREEDFUNCTIONS_H #define _THREEDFUNCTIONS_H ... ... #endifAlternativ versuchte ich es auch mit
#pragma onceBeides führte zu oben genannten Fehlermeldungen.
Die Microsoft Beschreibung des Error LNK 2005 habe ich mir zwar schon durchgelesen, werde aber nicht so recht daraus schlau, dort ist ja als Lösung etwas von Libaries die Rede, was solldas?
(In der Headerdatei tauchen tatsächlich ein paar Libary Nennungen auf, allerdings kann ich darauf keine der Tipps der MS Seite anwenden:#pragma comment(lib, "d3d9.lib") // for Direct3DCreate9 #pragma comment(lib, "d3dx9.lib") // for Direct3DCreate9 #pragma comment(lib, "dxguid.lib") // for Direct3DCreate9 #pragma comment(lib, "winmm.lib") //for timeGetTime)
Hat jemand also eine Idee, woran das liegen könnte und wie ich diese Link-Errors loswerde?
Danke und Gruß!
-
Probier mal /FORCE oder /FORCE:MULTIPLE
bis Du den Fehler lokalisiert hast.siehe z.B.: http://www.codeproject.com/buglist/linkererrors.asp?df=100&forumid=15354&exp=0&select=527004
-
Erhard Henkes schrieb:
Probier mal /FORCE oder /FORCE:MULTIPLE
bis Du den Fehler lokalisiert hast.Danke für den Tipp. Statt "Error" steht jetzt nur "Warning", ansonsten bleiben die Fehlermeldungen zunächst gleich. (Dei Anwendung ist aber ausführbar.)
Danach kam allerdings die folgende Meldung:
Generating code
Finished generating code
CIL library( CIL module) : warning LNK4006: "float (* funktionswert)[101]" (?funktionswert@@3PAY0GF@MA) already defined in CIL library( CIL module); second definition ignored
CIL library( CIL module) : warning LNK4006: "bool b_3DFenster" (?b_3DFenster@@3_NA) already defined in CIL library( CIL module); second definition ignoredGehe ich also recht in der Annahme, dass diese CIL libary Probleme bereitet?
Ich habe dann versucht, sie zu ignorieren:
ALT + F7 -> Linker -> Input -> Ignore specific libary ->
Dort habe ich CIL.lib und testweise CIL eingetragen.
Das brachte allerdings nichts (Die Fehlermeldungen blieben wie zuvor).Was kann ich stattdessen machen?
Danke und Gruß!
-
Bau mal alles beim Kompilieren komplett neu auf und schau Dir alle Schalter genau an.
http://msdn2.microsoft.com/en-US/library/1zzf962b.aspx
-
Erhard Henkes schrieb:
Bau mal alles beim Kompilieren komplett neu auf
Reicht dazu ein "Rebuild Solution"?
Erhard Henkes schrieb:
und schau Dir alle Schalter genau an.
Ähm: Was meinst Du mit "Schalter"? (Siehe Sig...)
Und hat die Fehlermeldung von oben (CIL libary) etwas zu sagen?
Danke und Gruß!
-
Ich stehe vor genau dem gleichen Problem mit genau den gleichen Resultaten.
Ich habe bei mir den Fehler
CComplex.obj : error LNK2005: "double __cdecl P2dBm(double)" (?P2dBm@@YANN@Z) ist bereits in AdaptiveAlgorithm.obj definiert. ...wobei der Fehler in den Klassen
LightModulator2D, LightModulator2DDoc, LightModulator2DView, MainFrm, PropertiesDlg, DlgPPM, PPMOutputDlg, GraphCtrl, Laserbeam, PlotCtrl, MfcPlot, Plot, CComplex, FastFourierTrans
auftritt und das bei jeder Funktion aus der Header Datei "MathExt.h", was insgesammt 365 Fehlermeldungen bringt.
MathExt.h wird nur von CComplex.h geladen und enthält die Anweisungen
#ifndef _MATHEXT_H_ #define _MATHEXT_H_ ... double P2dBm(double P) { return 30.0+10.0*log10(P);} ...Die Funktionen werden daher in der Header Datei definiert. CComplex wird wiederum nur geladen von
CComplex, Plot, Laserbeam, FastFourierTrans, GraphCtrl
AdaptiveAlgorithm, wo das ganze schon definiert sein worden soll lädt das ganze über ->FastFourierTrans->CComplex->MatheExt.
Wenn ich den Linkerschalter
/FORCE:MULTIPLEeinfüge dann werden daraus die Warnungen:
CComplex.obj :warning LNK4006: "double __cdecl P2dBm(double)" (?P2dBm@@YANN@Z) ist bereits in "AdaptiveAlgorithm.obj" definiert; zweite Definition wird ignoriert. ...Das bringt mir natürlich keine Lösung des Problems.
Ich wüsste gerne warum der Fehler überhaupt auftritt und wie ich ihn verhindere.
Matthias
-
dong schrieb:
Linking...
3dfunctions.obj : error LNK2005: "struct IDirect3D9 * g_pD3D" (?g_pD3D@@3PAUIDirect3D9@@A) already defined in mfc-testDlg.objDie Variable g_pD3D wurde mehrfach definiert. Variablendefinitionen haben in der Regel in Headern nichts verloren. Dort sollte nur eine Deklaration stehen, also
extern IDirect3D9* g_pD3D;oder so ähnlich. Das hat im Übrigen nichts mit Mehrfacheinbindung des Headers in einer Übersetzungseinheit zu tun (dagegen schützen include-guards), sondern mit der Einbindung in mehreren Übersetzungseinheiten. Definitionen von Variablen und Funktionen (außer inline) dürfen nur einmal im Programm existieren.
-
pospiech schrieb:
Ich wüsste gerne warum der Fehler überhaupt auftritt und wie ich ihn verhindere.
Ich habe es jetzt behoben indem ich alle Funktionen aus MathExt.h in Mathext.cpp verschoben habe und diese dem Projekt ebenfalls hinzugefügt habe.
Nur stellt sich mir nun die Frage warum das auftritt und wie die Schreiber von Bibliotheken das Problem lösen.
Matthias
-
pospiech schrieb:
Nur stellt sich mir nun die Frage warum das auftritt
Weil du Funktionen oder Variablen in einer Headerdatei definiert hast. Sobald diese Headerdatei in mehr als einer Übersetzungseinheit landet, sind diese Funktionen und Variablen mehrfach definiert, und der Linker weiß nicht, welche er benutzen soll. Davor schützen dich auch die Include Guards nicht, die wirken immer nur in einer Übersetzungseinheit.
-
pospiech schrieb:
pospiech schrieb:
Ich wüsste gerne warum der Fehler überhaupt auftritt und wie ich ihn verhindere.
Ich habe es jetzt behoben indem ich alle Funktionen aus MathExt.h in Mathext.cpp verschoben habe und diese dem Projekt ebenfalls hinzugefügt habe.
Nur stellt sich mir nun die Frage warum das auftritt und wie die Schreiber von Bibliotheken das Problem lösen.
Matthias
Man kann auch einfach "inline" davor schreiben, dann darf die Definition der Funktion auch in 100 TUs vorkommen.