是什么导致我的代码中出现 "error LNK2005: already defined in .obj" 错误?
What is causing the "error LNK2005: already defined in .obj" s errors in my code?
我想知道是什么导致了我的代码中的双重定义链接器错误。这让我感到困惑,因为似乎没有任何理由。我不认为我 #include
ing 任何 .h
文件的地方会导致这种情况,因为我的文件 #include
是线性结构的。
明确地说,我不是在问错误是什么意思,我是在问在我的代码中是什么导致了错误。我已经在这个网站(和其他网站)上研究过它的含义,但找不到与我的代码中可能导致它的原因相关的答案。
顺便说一下,我正在使用 Visual Studio 2017
错误如下:
1>ObjectHandler.cpp
1>Main.cpp
1>Generating Code...
1>ObjectHandler.obj : error LNK2005: "void __cdecl pixelsInit(void)" (?
pixelsInit@@YAXXZ) already defined in Main.obj
1>ObjectHandler.obj : error LNK2005: "void __cdecl pixelsUpdate(void)" (?
pixelsUpdate@@YAXXZ) already defined in Main.obj
1>ObjectHandler.obj : error LNK2005: "void __cdecl spritesInit(void)" (?
spritesInit@@YAXXZ) already defined in Main.obj
1>ObjectHandler.obj : error LNK2005: "void __cdecl spritesUpdate(void)" (?
spritesUpdate@@YAXXZ) already defined in Main.obj
1>ObjectHandler.obj : error LNK2005: "class std::vector<struct pixel,class
std::allocator<struct pixel> > pixels" (?pixels@@3V?$vector@Upixel@@V?
$allocator@Upixel@@@std@@@std@@A) already defined in Main.obj
1>ObjectHandler.obj : error LNK2005: "class std::map<class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> >,struct sprite,struct std::less<class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> > >,class std::allocator<struct std::pair<class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> > const ,struct sprite> > > sprites" (?sprites@@3V?
$map@V?$basic_string@DU?$char_traits@D@std@@V?
$allocator@D@2@@std@@Usprite@@U?$less@V?$basic_string@DU?
$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@U?$pair@$$CBV?
$basic_string@DU?$char_traits@D@std@@V?
$allocator@D@2@@std@@Usprite@@@std@@@2@@std@@A) already defined in Main.obj
1>fatal error LNK1169: one or more multiply defined symbols found
这是我的代码结构:
SimpleTypes.h:
#pragma once
struct loc {
int x;
int y;
int d;
int s;
};
struct color {
_int8 r;
_int8 g;
_int8 b;
_int8 a;
};
ComplexTypes.h:
#pragma once
#include "SimpleTypes.h"
#include <string>
struct pixel {
loc pos;
color col;
};
struct sprite {
std::string name;
std::string file;
loc pos;
};
ObjectHandler.cpp:
#include "ComplexTypes.h"
#include <string>
#include <map>
#include <vector>
std::vector<pixel> pixels;
std::map<std::string, sprite> sprites;
void pixelsInit(){};
void spritesInit(){};
void pixelsUpdate(){};
void spritesUpdate(){};
Main.cpp
#include "ObjectHandler.cpp"
int main() {
pixelsInit();
spritesInit();
while (true) {
pixelsUpdate();
spritesUpdate();
};
return 0;
}
在您的项目中,您正在编译 ObjectHandler.cpp
作为一个独立的翻译单元。同时,您还将 ObjectHandler.cpp
包含到 Main.cpp
中,它会作为 Main.cpp
.
的一部分再次编译
因此,ObjectHandler.cpp
中定义的所有内容都会在您的程序中定义两次。因此出现错误。
问题是:为什么要将 ObjectHandler.cpp
包含在 Main.cpp
中?你试图通过它实现什么目标?
而且,如果您出于某些非正统的原因,真的 want/have 将 ObjectHandler.cpp
包含到 Main.cpp
中并将其编译为 Main.cpp
的一部分,那么请停止编译 ObjectHandler.cpp
同时作为一个独立的翻译单元。
同时,在这种情况下,更传统的方法是为您的 ObjectHandler.cpp
编写一个合适的 ObjectHandler.h
文件。像
#pragma once
#include "ComplexTypes.h"
#include <string>
#include <map>
#include <vector>
extern std::vector<pixel> pixels;
extern std::map<std::string, sprite> sprites;
void pixelsInit();
void spritesInit();
void pixelsUpdate();
void spritesUpdate();
并将其包含在 Main.cpp
中。
您的 ObjectHandler.cpp
可能如下所示
#include "ObjectHandler.h"
std::vector<pixel> pixels;
std::map<std::string, sprite> sprites;
void pixelsInit(){}
void spritesInit(){}
void pixelsUpdate(){}
void spritesUpdate(){}
注意重要细节:.h
文件仅包含 声明 (函数没有主体,对象使用 extern
声明),而 .cpp
文件包含 定义 (函数有主体,对象声明时没有 extern
)
我想知道是什么导致了我的代码中的双重定义链接器错误。这让我感到困惑,因为似乎没有任何理由。我不认为我 #include
ing 任何 .h
文件的地方会导致这种情况,因为我的文件 #include
是线性结构的。
明确地说,我不是在问错误是什么意思,我是在问在我的代码中是什么导致了错误。我已经在这个网站(和其他网站)上研究过它的含义,但找不到与我的代码中可能导致它的原因相关的答案。
顺便说一下,我正在使用 Visual Studio 2017
错误如下:
1>ObjectHandler.cpp
1>Main.cpp
1>Generating Code...
1>ObjectHandler.obj : error LNK2005: "void __cdecl pixelsInit(void)" (?
pixelsInit@@YAXXZ) already defined in Main.obj
1>ObjectHandler.obj : error LNK2005: "void __cdecl pixelsUpdate(void)" (?
pixelsUpdate@@YAXXZ) already defined in Main.obj
1>ObjectHandler.obj : error LNK2005: "void __cdecl spritesInit(void)" (?
spritesInit@@YAXXZ) already defined in Main.obj
1>ObjectHandler.obj : error LNK2005: "void __cdecl spritesUpdate(void)" (?
spritesUpdate@@YAXXZ) already defined in Main.obj
1>ObjectHandler.obj : error LNK2005: "class std::vector<struct pixel,class
std::allocator<struct pixel> > pixels" (?pixels@@3V?$vector@Upixel@@V?
$allocator@Upixel@@@std@@@std@@A) already defined in Main.obj
1>ObjectHandler.obj : error LNK2005: "class std::map<class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> >,struct sprite,struct std::less<class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> > >,class std::allocator<struct std::pair<class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> > const ,struct sprite> > > sprites" (?sprites@@3V?
$map@V?$basic_string@DU?$char_traits@D@std@@V?
$allocator@D@2@@std@@Usprite@@U?$less@V?$basic_string@DU?
$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@U?$pair@$$CBV?
$basic_string@DU?$char_traits@D@std@@V?
$allocator@D@2@@std@@Usprite@@@std@@@2@@std@@A) already defined in Main.obj
1>fatal error LNK1169: one or more multiply defined symbols found
这是我的代码结构:
SimpleTypes.h:
#pragma once
struct loc {
int x;
int y;
int d;
int s;
};
struct color {
_int8 r;
_int8 g;
_int8 b;
_int8 a;
};
ComplexTypes.h:
#pragma once
#include "SimpleTypes.h"
#include <string>
struct pixel {
loc pos;
color col;
};
struct sprite {
std::string name;
std::string file;
loc pos;
};
ObjectHandler.cpp:
#include "ComplexTypes.h"
#include <string>
#include <map>
#include <vector>
std::vector<pixel> pixels;
std::map<std::string, sprite> sprites;
void pixelsInit(){};
void spritesInit(){};
void pixelsUpdate(){};
void spritesUpdate(){};
Main.cpp
#include "ObjectHandler.cpp"
int main() {
pixelsInit();
spritesInit();
while (true) {
pixelsUpdate();
spritesUpdate();
};
return 0;
}
在您的项目中,您正在编译 ObjectHandler.cpp
作为一个独立的翻译单元。同时,您还将 ObjectHandler.cpp
包含到 Main.cpp
中,它会作为 Main.cpp
.
因此,ObjectHandler.cpp
中定义的所有内容都会在您的程序中定义两次。因此出现错误。
问题是:为什么要将 ObjectHandler.cpp
包含在 Main.cpp
中?你试图通过它实现什么目标?
而且,如果您出于某些非正统的原因,真的 want/have 将 ObjectHandler.cpp
包含到 Main.cpp
中并将其编译为 Main.cpp
的一部分,那么请停止编译 ObjectHandler.cpp
同时作为一个独立的翻译单元。
同时,在这种情况下,更传统的方法是为您的 ObjectHandler.cpp
编写一个合适的 ObjectHandler.h
文件。像
#pragma once
#include "ComplexTypes.h"
#include <string>
#include <map>
#include <vector>
extern std::vector<pixel> pixels;
extern std::map<std::string, sprite> sprites;
void pixelsInit();
void spritesInit();
void pixelsUpdate();
void spritesUpdate();
并将其包含在 Main.cpp
中。
您的 ObjectHandler.cpp
可能如下所示
#include "ObjectHandler.h"
std::vector<pixel> pixels;
std::map<std::string, sprite> sprites;
void pixelsInit(){}
void spritesInit(){}
void pixelsUpdate(){}
void spritesUpdate(){}
注意重要细节:.h
文件仅包含 声明 (函数没有主体,对象使用 extern
声明),而 .cpp
文件包含 定义 (函数有主体,对象声明时没有 extern
)