Linker errors even though I prevent them with #ifndef
I am getting linker errors that suggest I am not using #ifndef and #define.
1>TGALoader.obj : error LNK2005: "struct TGA tga" (?tga@@3UTGA@@A) already defined in main.obj 1>TGALoader.obj : error LNK2005: "struct TGAHeader tgaheader" (?tgaheader@@3UTGAHeader@@A) already defined in main.obj 1>TGALoader.obj : error LNK2005: "unsigned char * uTGAcompare" (?uTGAcompare@@3PAEA) already defined in main.obj 1>TGALoader.obj : error LNK2005: "unsigned char * cTGAcompare" (?cTGAcompare@@3PAEA) already defined in main.obj 1>LINK : warning LNK4098: defaultlib 'LIBCMTD' conflicts with use of other libs; use /NODEFAULTLIB:library
I have included a header file Texture.h and tga.h from the nehe opengl tutorials into my project. I have
#ifndef TGAISCOOL
#define TGAISCOOL
#endif
in my tga.h file. If I incl开发者_如何学JAVAude this more than once, I get the errors from the linker that I pasted above. The first two are from texture.h though the situation is the same.
Any ideas on what is wrong?
You're not doing anything wrong. The problem is with the Tga.h file you got from NeHe. This header file defines four objects which means that if you include the file in different translation units the symbols for these will appear multiple times and that is what the linker is complaining about.
The solution is to move the definitions of these objects into the Tga.cpp file.
The lines in Tga.h that previously had the definitions should now read
extern TGAHeader tgaheader;
extern TGA tga;
extern GLubyte uTGAcompare[12];
extern GLubyte cTGAcompare[12];
with the original versions of these lines now in Tga.cpp
The problem is you are putting definitions in your header file instead of declarations.
Include guards only work for multiple includes of a single translation unit (i.e a source file). If you compile multiple translation units, each one will see the contents of your header file.
So, instead of putting this definition in your header file:
struct TGA tga;
You want to put this declaration in your header file:
/* whatever.h */
extern struct TGA tga;
And then add the definition in a source file:
/* whatever.c */
#include "whatever.h"
struct TGA ta;
The rule of thumb is that definitions go in source files and declarations go in header files.
There's no reason to conclude that #ifndef isn't working properly. What the error message is saying is that you have items with the same name defined in multiple translation units (.obj files). The link process is therefore failing.
As for how to fix it, we need to see more code.
Change your Tga.H like this:
#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
Add the following lines in your TGALoader.cpp file on top:
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};
精彩评论