简体   繁体   English

如何避免头文件中定义的变量的LNK2005链接器错误?

[英]How can I avoid the LNK2005 linker error for variables defined in a header file?

I have 3 cpp files that look like this 我有3个cpp文件,看起来像这样

#include "Variables.h"
void AppMain() {
    //Stuff...
}

They all use the same variables inside them so they have the same headers but I get stuff like this 他们都在里面使用相同的变量,所以他们有相同的标题,但我得到这样的东西

1>OnTimer.obj : error LNK2005: "int slider" (?slider@@3HA) already defined in AppMain.obj

Why is that? 这是为什么?

Keep in mind that a #include is roughly like cutting and pasting the included file inside the source file that includes it (this is a rough analogy, but you get the point). 请记住,#include类似于剪切和粘贴包含它的源文件中包含的文件(这是一个粗略的类比,但你明白了)。 That means if you have: 这意味着如果你有:

int x;  // or "slider" or whatever vars are conflicting

in the header file and that header file is included by three source files in a program, then they will all have a global named x defined that will conflict. 在头文件中,头文件包含在一个程序中的三个源文件中,然后它们都将具有一个将被冲突的全局命名x。

What you want to do is define the variable as extern so that the .cpp files will all get the declaration, and then in ONE of your .cpp files give the actual definition. 你想要做的是将变量定义为extern,以便.cpp文件都将获得声明,然后在一个.cpp文件中给出实际的定义。

in Variables.h: 在Variables.h中:

extern int x;

in SomeSourceFile.cpp 在SomeSourceFile.cpp中

int x;

Of course, I'd recommend against globals, but if you must use them this would keep them from conflicting. 当然,我建议不要使用全局变量,但如果你必须使用它们,这将使它们不会发生冲突。

Because "int slider" is already defined in another file? 因为“int slider”已经在另一个文件中定义了? Check that you have header guards... 检查你是否有头部防护装置......

#ifndef _VARIABLES_H_
#define _VARIABLES_H_

int slider;

#endif

If it is across multiple translation units, and you do want the variables to be different (ie not global), then maybe declare them in an anonymous namespace: 如果它跨越多个翻译单元,并且您确实希望变量不同(即不是全局变量),那么可以在匿名名称空间中声明它们:

namespace {
    int slider;
}

If you do want them global, look to James' solution. 如果你确实希望它们具有全局性,那就看看James的解决方案。

This is because the compiler compiles each .cpp file separately, creating a .obj file for each one. 这是因为编译器分别编译每个.cpp文件,为每个文件创建一个.obj文件。 Your header appears to have something like: 您的标题似乎有类似于:

int slider;

When this is included into each of your three .cpp file, you get three copies of the int slider variable, just as if you had declared it in each .cpp file. 当这包含在你的三个.cpp文件中的每一个中时,你会获得int slider变量的三个副本,就像你在每个.cpp文件中声明它一样。 The linker complains about this because you haven't have three different things with the same name. 链接器抱怨这个,因为你没有三个具有相同名称的不同东西。

What you probably want to do is change your header file to read: 您可能想要做的是将头文件更改为:

extern int slider;

This tells the compiler that there is a slider variable somewhere, but possibly not here, and lets the linker figure it out. 这告诉编译器某处有一个slider变量,但可能不在这里,并让链接器弄清楚它。 Then, in one .cpp file: 然后,在一个 .cpp文件中:

int slider;

gives the linker one actual variable to link. 为链接器提供一个实际变量来链接。

I know that this is an old thread, but I came across this as one of the first search results from Google. 我知道这是一个旧帖子,但我发现这是谷歌的第一个搜索结果之一。 I solved the problem by placing the variable static. 我通过将变量静态放置来解决问题。

namespace Vert
{
   static int i;
}

I tried extern and in my situation that didn't seem to solve the problem. 我尝试了extern,在我的情况下似乎没有解决问题。

What is happening is that each of the variables from Variables.h are given global scope for each of the individual c files. 发生的事情是Variables.h中的每个变量都为每个单独的c文件提供了全局范围。 When the linker compiles all the c files, it sees multiple variables with the same name. 当链接器编译所有c文件时,它会看到多个具有相同名称的变量。

If you are wanting to use variables from the header file as global variables, then you will have to use the keyword "extern" in front of all of them, and in the main file don't use the keyword extern. 如果您想要将头文件中的变量用作全局变量,那么您必须在所有变量前面使用关键字“extern”,并且在主文件中不要使用关键字extern。

main c: 主要c:

int n_MyVar;

other files: 其他文件:

extern int n_MyVar;

You can create two files Variables.h and EVariables.h, or just declare the variables in the main.cpp file. 您可以创建两个文件Variables.h和EVariables.h,或者只是在main.cpp文件中声明变量。

A much better way to do this is to create a class of Variables and pass a reference to the class. 更好的方法是创建一个Variables类并传递对该类的引用。

如果通过“Variables.h”多次包含的变量声明为const,也可以避免这种链接错误。

I had this error too although I work with extern definitions. 虽然我使用extern定义,但我也遇到了这个错误。 The problem was initializing the variables in the extern definitions too: 问题是初始化外部定义中的变量:

ID3D11VertexShader*         g_pVertexShader = nullptr;
...
extern ID3D11VertexShader*  g_pVertexShader = nullptr;  // here's the problem 

=> error =>错误

ID3D11VertexShader*         g_pVertexShader = nullptr;
...
extern ID3D11VertexShader*  g_pVertexShader;           // without initializing  

=> no error, problem solved =>没有错误,问题解决了

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM