简体   繁体   English

双重包含的C ++ / SDL问题

[英]C++/SDL problem of double inclusion

I'm getting this error from compilator: 我从编译器收到此错误:

1>Linking...
1>main.obj : error LNK2005: "int g_win_flags" (?g_win_flags@@3HA) already defined in init.obj
1>main.obj : error LNK2005: "struct SDL_Surface * g_screen" (?g_screen@@3PAUSDL_Surface@@A) already defined in init.obj
1>MSVCRTD.lib(cinitexe.obj) : warning LNK4098: defaultlib 'msvcrt.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
1>.\Debug\Heroes are back!.exe : fatal error LNK1169: one or more multiply defined symbols found

It looks like that g_win_flags and g_screen are twice included, but I don't understand why. 似乎两次包含了g_win_flags和g_screen,但是我不明白为什么。 Here is the source: 来源如下:

main.cpp main.cpp中

#include <iostream>
#include "dec.h"
#include "init.h"

int main(int argc, char *argv[]){

    init();
    return 0;
}

dec.h dec.h

#ifndef DEC_H
#define DEC_H

#include <SDL.h>
#include <iostream>

#pragma comment(lib, "SDL.lib")
#pragma comment(lib, "SDLmain.lib")

using namespace std;

int g_win_flags = SDL_HWSURFACE|SDL_DOUBLEBUF;

SDL_Surface *g_screen = NULL;

#endif

init.h init.h里

#ifndef INIT_H
#define INIT_H

bool init();

#endif

init.cpp init.cpp

#include "dec.h"

bool init(){
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) == -1){
        cerr << "Unable to initialize SDL" << endl;
        return false;
    }
    g_screen = SDL_SetVideoMode(640, 480, 0, g_win_flags);

    return true;
}

Can someone help? 有人可以帮忙吗? Thanks in advance and have a nice day :) 在此先感谢,祝您有美好的一天:)

You define and initialize the variables in the header. 您定义并初始化标题中的变量。

You should just declare them in the header (dec.h) without any initializers: 您应该只在标头(dec.h)中声明它们,而无需任何初始化程序:

extern int g_win_flags;
extern SDL_Surface *g_screen;

Then define them once in one file - presumably dec.cpp - with the initializations. 然后使用初始化在一个文件(大概为dec.cpp)中定义一次。

As it was, you were defining them in every source file that included 'dec.h' and then running foul of the ODR - One Definition Rule. 照原样,您正在每个包含'dec.h'的源文件中定义它们,然后违反了ODR-一个定义规则。

in dec.h you want 在dec.h中

extern int g_win_flags;

extern SDL_Surface *g_screen;

and then to define and initalise them in just dec.cpp 然后在dec.cpp中定义和初始化它们

Update: 更新:

#include "dec.h"
int g_win_flags = SDL_HWSURFACE|SDL_DOUBLEBUF;

SDL_Surface *g_screen = NULL;

The general rule of thumb is "nothing in a header file should take up any space in the output of the compiler". 一般的经验法则是“头文件中的任何内容都不应占用编译器输出中的任何空间”。 (There are exceptions to this obviously) (显然有例外)

In practice this means extern variable declarations are fine, as are function declarations, but not definitions. 在实践中,这意味着外部变量声明和函数声明一样好,但定义不是。

You have included files into two different source files (init.cpp and main.cpp) that define instantiated variables. 您已将文件包含在定义实例化变量的两个不同的源文件(init.cpp和main.cpp)中。

You need a way to be sure they are 'externed' in all but one source file. 您需要一种方法来确保它们在除一个源文件之外的所有文件中都被“附加”。

Well, I tried to do what you've told me guys, but compilator is complaining: 好吧,我试图做您告诉我的事情,但是编译器在抱怨:

1>.\heroes are back!\dec.cpp(2) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>.\heroes are back!\dec.cpp(4) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>.\heroes are back!\dec.cpp(4) : error C2040: 'g_screen' : 'int' differs in levels of indirection from 'SDL_Surface *'

Here is the dec.h 这是dec.h

#ifndef DEC_H
#define DEC_H

#include <SDL.h>
#include <iostream>

#pragma comment(lib, "SDL.lib")
#pragma comment(lib, "SDLmain.lib")

using namespace std;

extern int g_win_flags;

extern SDL_Surface *g_screen;

#endif

dec.cpp dec.cpp

#include "dec.h"
g_win_flags = SDL_HWSURFACE|SDL_DOUBLEBUF;

g_screen = NULL;

What is wrong in this code? 该代码有什么问题? Sorry for asking dumb questions, but I'm only learning C++ :) 很抱歉提出愚蠢的问题,但我只在学习C ++ :)

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

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