在.h文件中,我将全局变量声明为:
#pragma data_seg(".shared")
#ifndef DEF_VARX
#define DEF_VARX
int VARX=0;
#endif /*DEF_VARX*/
#pragma data_seg()
#pragma comment(linker, "/SECTION:.shared,RWS")
但是如果我将这个文件包含在多个cpp文件中,当我尝试编译时,我得到“错误LNK2005:”int VARX“(?VARX @@ 3HA)已在Dll.obj中定义”错误。如果我只包含一个cpp文件,则不会遇到任何问题。
不是#IFNDEF ....检查是否足以阻止这种情况?我错过了什么吗?
答案 0 :(得分:3)
这种行为的原因是,您编译了行
int VARX=0;
到每个.obj文件中。这可以编译,但在链接时符号会被多重定义,这是非法的。使用
extern int VARX;
头文件中的和
int VARX=0;
在一个(且只有一个)源文件中解决了这个问题。
答案 1 :(得分:2)
我认为你应该在.h中转发声明变量,然后在.cpp的共享部分中定义它,如:
// in a header file
#pragma once
extern int VARX;
// in a .cpp
#pragma data_seg(".shared")
int VARX=0;
#pragma data_seg()
#pragma comment(linker, "/SECTION:.shared,RWS")
答案 2 :(得分:1)
问题在于,您可以防止为给定的翻译单元多次包含该文件。 (对于给定的说cpp文件)
但是如果你的几个cpp包含这个VARX.H,那么你将拥有这个变量的多个定义。
相反,您应该只在.H文件中声明变量,但只在一个位置将其初始化为0.
答案 3 :(得分:1)
是的,你错过了extern关键字。
在您的标头文件中,使用:
extern int VARX;
在源文件中,实际为变量声明空间:
int VARX = 0;
答案 4 :(得分:0)
ifdef阻止它用于separe对象文件。当标题包含在多个源(cpp)文件中时,将在所有文件中取消定义VARX。考虑在头文件中将其声明为extern,并在一个cpp文件中初始化。
答案 5 :(得分:0)
问题是您必须将文件包含在多个编译单元中。假设你有a.cpp和b.cpp。两者都包含您的头文件。因此编译器将单独编译(和预处理),因此对于这两个文件,尚未定义DEF_VARX。当您将目标文件链接在一起时,链接器会注意到存在名称冲突。
正如其他人所建议的,解决方案是将其声明为'extern',然后将实际值放在cpp文件中,因此它只编译一次,并链接到没有名称冲突的所有内容。