开发者

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};
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜