2010-01-23 4 views
3

Je reçois des erreurs d'éditeur de liens qui suggèrent que je n'utilise pas #ifndef et #define.Erreurs de lieur même si je les empêche aveC#ifndef

1> TGALoader.obj: erreur LNK2005: "struct TGA TGA" déjà défini dans main.obj 1> TGALoader.obj (tga 3UTGA @@ @@ A?): Erreur LNK2005: " struct tGAHeader tgaheader » déjà défini dans main.obj 1> TGALoader.obj (tgaheader @@ 3UTGAHeader @@ A?): erreur LNK2005: "unsigned char * uTGAcompare"(? uTGAcompare @@ 3PAEA) déjà défini dans main.obj 1> TGALoader.obj: erreur LNK2005: "unsigned char * cTGAcompare" (? cTGAcompare @@ 3PAEA) déjà défini dans main.obj 1> LINK: avertissement LNK4098: defaultlib 'LIBCMTD' en conflit avec utilisation d'autres bibliothèques; utiliser /NODEFAULTLIB: bibliothèque

J'ai inclus un fichier d'en-tête Texture.h et tga.h des tutoriels Nehe opengl dans mon projet . J'ai

#ifndef TGAISCOOL 
#define TGAISCOOL 
#endif 

dans mon fichier tga.h. Si je l'inclut plus d'une fois, j'obtiens les erreurs de l'éditeur de liens que j'ai collé ci-dessus. Les deux premiers proviennent de texture.h bien que la situation soit la même.

Des idées sur ce qui ne va pas?

+1

Afficher plus de code. – SoapBox

+0

Les erreurs du lieur n'ont rien à voir avec '# ifndef'. Les gardes d'en-tête empêchent seulement les conflits de redéfinition au moment de la compilation, c'est-à-dire par unité de traduction. Ce problème est entièrement différent! –

Répondre

6

Vous ne faites rien de mal. Le problème est avec le fichier Tga.h que vous avez reçu de NeHe. Ce fichier d'en-tête définit quatre objets, ce qui signifie que si vous incluez le fichier dans différentes unités de traduction, les symboles apparaîtront plusieurs fois et c'est ce dont se plaint l'éditeur de liens.

La solution consiste à déplacer les définitions de ces objets dans le fichier Tga.cpp.

Les lignes Tga.h qui avaient déjà lu les définitions devraient maintenant

extern TGAHeader tgaheader; 
extern TGA tga; 

extern GLubyte uTGAcompare[12]; 
extern GLubyte cTGAcompare[12]; 

avec les versions originales de ces lignes maintenant Tga.cpp

3

Il n'y a aucune raison de conclure que #ifndef ne fonctionne pas correctement. Ce que le message d'erreur dit, c'est que vous avez des éléments avec le même nom défini dans plusieurs unités de traduction (fichiers .obj). Le processus de lien échoue donc.

En ce qui concerne la façon de résoudre ce problème, nous devons voir plus de code.

+0

Je suis curieux de savoir comment gérer cette demande. J'ai beaucoup de nombreuses lignes de codes à coller. Qu'est-ce que je dois inclure exactement? Y at-il un endroit où je peux mettre toute ma solution zippée? – bobber205

+1

@ bobber205: http://gist.github.com/ est un moyen facile de partager des choses, mais aussi vous devriez essayer de réduire à un cas de test minimal reproductible. En d'autres termes, se débarrasser de tout ce que vous pouvez tout en démontrant encore l'échec. – ephemient

7

Le problème est que vous placez des définitions dans votre fichier d'en-tête au lieu de déclarations.

Les gardes d'inclusion ne fonctionnent que pour plusieurs inclusions d'une même unité de traduction (c'est-à-dire un fichier source). Si vous compilez plusieurs unités de traduction, chacune verra le contenu de votre fichier d'en-tête.

Ainsi, au lieu de mettre cette définition dans votre fichier d'en-tête:

struct TGA tga; 

Vous voulez mettre cette déclaration dans votre fichier d'en-tête:

/* whatever.h */ 
extern struct TGA tga; 

Et puis ajoutez la définition dans un fichier source:

/* whatever.c */ 
#include "whatever.h" 

struct TGA ta; 

La règle générale est que les définitions vont dans les fichiers source et les déclarations vont dans les fichiers d'en-tête.

+0

Les définitions statiques/en ligne sont correctes dans les fichiers d'en-tête; c'est d'avoir des entités externes visibles dans plusieurs unités de traduction où des problèmes surviennent. – ephemient

+0

@ephemient - Je concède définitivement le point sur les définitions en ligne. Mais alors que les définitions statiques fonctionnent techniquement bien dans les fichiers d'en-tête, je pense qu'ils sont d'un style si horrible qu'ils ne valent pas la peine d'être mentionnés. –

+0

Je voulais dire "bien" comme dans "œuvres", pas comme dans "bon goût" ;-) – ephemient

2

Changez votre Tga.H comme ceci:

#ifndef Tga_H 
#define Tga_H 
#include "Texture.h" 



struct TGAHeader 
{ 
    GLubyte Header[12];         // TGA File Header 
} ; 


struct TGA 
{ 
    GLubyte  header[6];        // First 6 Useful Bytes From The Header 
    GLuint  bytesPerPixel;       // Holds Number Of Bytes Per Pixel Used In The TGA File 
    GLuint  imageSize;        // Used To Store The Image Size When Setting Aside Ram 
    GLuint  temp;         // Temporary Variable 
    GLuint  type; 
    GLuint  Height;         //Height of Image 
    GLuint  Width;         //Width ofImage 
    GLuint  Bpp;         // Bits Per Pixel 
} ; 


extern TGAHeader tgaheader;         // TGA header 
extern TGA tga;            // TGA image data 



extern GLubyte uTGAcompare[12]; // Uncompressed TGA Header 
extern GLubyte cTGAcompare[12]; // Compressed TGA Header 
bool LoadTGA(Texture * , char *); 
bool LoadUncompressedTGA(Texture *, char *, FILE *); // Load an Uncompressed file 
bool LoadCompressedTGA(Texture *, char *, FILE *);  // Load a Compressed file 

#endif 

Ajoutez les lignes suivantes dans votre fichier TGALoader.cpp sur:

TGAHeader tgaheader; 
TGA tga; 
GLubyte uTGAcompare[12] = {0,0,2, 0,0,0,0,0,0,0,0,0}; 
GLubyte cTGAcompare[12] = {0,0,10,0,0,0,0,0,0,0,0,0}; 
Questions connexes