Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

10.09.2012, 21:23

error LNK2005 already defined

Programmiersprache: c++
Programmierumgebung: Visual c++
Library: d3d9.lib
Buch: 3D-Spieleprogrammierung von David Scherfgen

Ich habe erfolgreich eine Anwendung geschrieben, welche ohne die Tribaseengine, Direct3D initialisiert und ein Dreieck zeichnet.

Darauf hin habe ich versucht diese Anwendung unter der Verwendung von OOP neu zu schreiben.

Dafür habe ich folgende Header:
vertexs.h
init3d.h
basicheader.h

und folgende cpp-files:
main.cpp
vertexs.cpp
init3d.cpp

verwendet.

vertexs.h:

Quellcode

1
2
3
4
5
#pragma once
#ifndef _vertexs_h_#define _vertexs_h_
#include "basicheader.h"
//stuff
#endif



init3d.h:

Quellcode

1
2
3
4
5
#pragma once
#ifndef _init3d_h_#define _init3d_h_
#include "basicheader.h"#include "vertexs.h"
//stuff
#endif



basicheader.h:

Quellcode

1
2
3
4
#pragma once
#ifndef _basicheader_h_#define _basicheader_h_
#include <Windows.h>#include <d3d9.h>#include <math.h>
#endif



init3d.cpp:

Quellcode

1
2
#include "init3d.h"
//stuff



vertexs.cpp:

Quellcode

1
2
#include "vertexs.h"
const DWORD vertexs::fvfdw = D3DFVF_XYZ | D3DFVF_DIFFUSE;



main.cpp

Quellcode

1
2
3
#include "vertexs.h"#include "init3d.h"
#include <Windows.h>#include <math.h>#include <d3d9.h>
//stuff



Nun erhalte ich folgende Fehlermeldung:

Zitat

Zitat

1>main.obj : error LNK2005: "struct IDirect3DDevice9 * d3ddp" (?d3ddp@@3PAUIDirect3DDevice9@@A) already defined in init3d.obj

Zitat

1>main.obj : error LNK2005: "struct _D3DMATRIX d3dmatrix0" (?d3dmatrix0@@3U_D3DMATRIX@@A) already defined in init3d.obj

Zitat

1>main.obj : error LNK2005: "struct _D3DPRESENT_PARAMETERS_ ppd3d" (?ppd3d@@3U_D3DPRESENT_PARAMETERS_@@A) already defined in init3d.obj

Zitat

1>main.obj : error LNK2005: "struct vertexs * vertexsa" (?vertexsa@@3PAUvertexs@@A) already defined in init3d.obj

Zitat

1>main.obj : error LNK2005: "struct IDirect3D9 * d3dp" (?d3dp@@3PAUIDirect3D9@@A) already defined in init3d.obj

Zitat

1>C:\Geogame\Geogame1\Debug\Geogame1.exe : fatal error LNK1169: one or more multiply defined symbols found
Ich würde das Project gerne in die oben beschriebenen files aufgespalten lassen.
Dafür ist es jedoch unabdinglich, dass ich einen selbst definierten Header zweimal includieren kann.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

10.09.2012, 21:30

Ich vermute mal, du hast in deinen Headern globale Variablen definiert? Wenn dem so ist, dann werden diese Variablen natürlich in jeder .cpp, die den Header included, neu definiert. Schau dir mal das Schlüsselwort extern an.

Abgesehen davon vielleicht noch ein paar Anmerkungen:
1) Namen, die mit _ beginnen, sind im global Namespace reserviert und sollten dort daher nicht benutzt werden.
2) Ich würde das #pragma once in die Include Guards setzen, da ich mir nicht sich bin, ob Compiler, die das Pragma nicht kennen, die Include Guards optimieren können, wenn diese nicht das ganze File umschließen.
3) Die Mehrzahl von vertex ist vertices. ;)

3

10.09.2012, 22:41

ich hab die globalen Variablen um die Bezeichnung extern erweitert. Das pragma once gelöscht und bei den Symbolen das vorangestellte "_" entfernt.

nun erhalte ich folgenden Fehler:

Zitat

Zitat

1>init3d.obj : error LNK2001: unresolved external symbol "struct _D3DMATRIX d3dmatrix0" (?d3dmatrix0@@3U_D3DMATRIX@@A)

Zitat

1>init3d.obj : error LNK2001: unresolved external symbol "struct vertexs * vertexsa" (?vertexsa@@3PAUvertexs@@A)

Zitat

1>init3d.obj : error LNK2001: unresolved external symbol "struct IDirect3DDevice9 * d3ddp" (?d3ddp@@3PAUIDirect3DDevice9@@A)

Zitat

1>main.obj : error LNK2001: unresolved external symbol "struct IDirect3DDevice9 * d3ddp" (?d3ddp@@3PAUIDirect3DDevice9@@A)

Zitat

1>init3d.obj : error LNK2001: unresolved external symbol "struct _D3DPRESENT_PARAMETERS_ ppd3d" (?ppd3d@@3U_D3DPRESENT_PARAMETERS_@@A)

Zitat

1>init3d.obj : error LNK2001: unresolved external symbol "struct IDirect3D9 * d3dp" (?d3dp@@3PAUIDirect3D9@@A)

Zitat

1>C:\Geogame\Geogame1\Debug\Geogame1.exe : fatal error LNK1120: 5 unresolved externals

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

4

10.09.2012, 22:44

Naja, extern sagt, dass die Variable in einem anderen .cpp File definiert wird. Du musst also die Variable in einem .cpp File deiner Wahl auch nochmal richtig definieren. ;)

5

10.09.2012, 22:57

Das funktioniert jetzt.

Aber wie verhält es sich wenn ich in einem Header eine class oder ein struct definiere.

muster.h:

Quellcode

1
2
struct muster{  int var1;   int var2;   muser2 muster2instance;
    void methode1();    int methode2(parametertyp1,parametertyp2);};



Wenn jetzt dieser Header 2 oder mehrmals includiert werden würde, würde ich dann bei struct muster ebenfalls als extern voransetzen?
Und wenn ja, welchen Sinn haben dann überhaupt Header?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

10.09.2012, 22:58

Das ist etwas Anderes, da definierst du ja kein Objekt sondern nur eine Klasse. ;)

7

10.09.2012, 23:04

Dann noch was:

Welche Bedeutung hat der Operator : also nur einmal Doppelpunkt.Aber nicht beim Vererben sondern wenn dieser Operator nach einem Konstruktor steht. So was habe ich mal bei dem Spiel Galactica, welches auf der CD des 3D-Spielebuches von David Scherfgen mitgeliefert wurde, gesehen.
In Galactica.h ist line 54 ist das zu sehen.
Sofern du dieses Programm hast.

Quellcode

1
inline CGalactica()     : m_pStateBlock(NULL)       , m_pIntro(NULL)        , m_pMainMenu(NULL)     , m_pGame(NULL)     , m_GameState((EGameState)(0))      , m_fTime(0.0f)     , m_pFont1(NULL)        , m_pFont2(NULL)        , m_pBriefing(NULL)     , m_pAction(NULL)   {       ZeroMemory(&m_Config, sizeof(m_Config));    }

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »hetlock« (10.09.2012, 23:13)


dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

8

11.09.2012, 00:10

Das ist eine sog. Initialisierungsliste, sollte eigentlich in jedem C++ Grundlagenbuch behandelt werden... ;)

9

12.09.2012, 21:35

Ich habe wirklich versucht das Headerproblem mit den redefinitions zu lösen. Aber ich schaffe das nicht.

Das erste Problem ist, dass, wenn ich includeguards verwende, visual studio nicht mehr diese Syntaxprüfung durchführt. Jetzt müsste ich jedes Mal, wenn ich den Code ändere diese includeguards löschen und danach wieder schreiben.

In dem c++-Buch mit dem ich c++ gelernt habe ist nicht erwähnt wie ich Headerfiles organisieren muss um redefinitions zu unterbinden.
Kenn jemand eine Seite oder Link, welcher beschreibt wie Headerfiles zu implementieren und einzubinden sind und zwar so, dass Visual Studio keine Fehlermeldungen mehr anzeigt.

Werbeanzeige