链接器错误,即使我用#ifndef阻止它们

bob*_*205 4 c++ linker linker-errors visual-studio-2008

我收到链接器错误,表明我没有使用#ifndef和#define.

1> TGALoader.obj:错误LNK2005:"struct TGA tga"(?tga @@ 3UTGA @@ A)已在main.obj中定义1> TGALoader.obj:错误LNK2005:"struct TGAHeader tgaheader"(?tgaheader @@ 3UTGAHeader @@ A)已在main.obj中定义1> TGALoader.obj:错误LNK2005:"unsigned char*uTGAcompare"(?uTGAcompare @@ 3PAEA)已在main.obj中定义1> TGALoader.obj:错误LNK2005:"unsigned char*cTGAcompare"(?cTGAcompare @@ 3PAEA)已在main.obj中定义1> LINK:警告LNK4098:defaultlib'LIBCMTD'与使用其他库冲突; 使用/ NODEFAULTLIB:库

我已经将一个头文件Texture.h和tga.h从nehe opengl教程中包含到我的项目中.我有

#ifndef TGAISCOOL
#define TGAISCOOL
#endif
Run Code Online (Sandbox Code Playgroud)

在我的tga.h文件中.如果我不止一次地包含它,我会从上面粘贴的链接器中获取错误.前两个来自texture.h虽然情况相同.

关于什么是错的任何想法?

R S*_*hko 7

问题是你在头文件而不是声明中放置定义.

包含保护仅适用于单个翻译单元(即源文件)的多个包含.如果您编译多个翻译单元,每个翻译单元都会看到您的头文件的内容.

因此,而不是将此定义放在头文件中:

struct TGA tga;
Run Code Online (Sandbox Code Playgroud)

您想将此声明放在头文件中:

/* whatever.h */
extern struct TGA tga;
Run Code Online (Sandbox Code Playgroud)

然后在源文件中添加定义:

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

struct TGA ta;
Run Code Online (Sandbox Code Playgroud)

经验法则是定义放在源文件中,声明放在头文件中.


Tro*_*our 6

你没有做错任何事.问题出在你从NeHe获得的Tga.h文件中.此头文件定义了四个对象,这意味着如果您将文件包含在不同的翻译单元中,这些文件的符号将出现多次,这就是链接器所抱怨的内容.

解决方案是将这些对象的定义移动到Tga.cpp文件中.

现在应该阅读以前有定义的Tga.h中的行

extern TGAHeader tgaheader;
extern TGA tga;

extern GLubyte uTGAcompare[12];
extern GLubyte cTGAcompare[12];
Run Code Online (Sandbox Code Playgroud)

这些行的原始版本现在在Tga.cpp中