【问题标题】:C++/SDL problem of double inclusionC++/SDL 双重包含问题
【发布时间】:2010-11-03 18:22:39
【问题描述】:

我从编译器收到此错误:

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

看起来 g_win_flags 和 g_screen 被包含了两次,但我不明白为什么。 以下是出处:

main.cpp

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

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

    init();
    return 0;
}

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

#ifndef INIT_H
#define INIT_H

bool init();

#endif

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;
}

有人可以帮忙吗?在此先感谢,祝您有美好的一天:)

【问题讨论】:

  • 不应在头文件中定义除外部声明以外的变量。
  • 仅供参考,这不是编译器错误,而是链接器错误。

标签: c++ sdl include-guards


【解决方案1】:

您在标题中定义和初始化变量。

您应该只在标头 (dec.h) 中声明它们,而无需任何初始化程序:

extern int g_win_flags;
extern SDL_Surface *g_screen;

然后在一个文件中定义它们一次 - 大概是 dec.cpp - 与初始化。

事实上,您在每个包含“dec.h”的源文件中定义它们,然后违反了 ODR - 一个定义规则。

【讨论】:

    【解决方案2】:

    你想要的 dec.h

    extern int g_win_flags;
    
    extern SDL_Surface *g_screen;
    

    然后在 dec.cpp 中定义和初始化它们

    更新:

    #include "dec.h"
    int g_win_flags = SDL_HWSURFACE|SDL_DOUBLEBUF;
    
    SDL_Surface *g_screen = NULL;
    

    一般的经验法则是“头文件中的任何内容都不应占用编译器输出中的任何空间”。 (显然有例外)

    在实践中,这意味着外部变量声明很好,函数声明也很好,但不是定义。

    【讨论】:

      【解决方案3】:

      您已将文件包含到定义实例化变量的两个不同源文件(init.cpp 和 main.cpp)中。

      您需要一种方法来确保它们在除一个源文件之外的所有文件中都被“外部”。

      【讨论】:

      • 见下面乔纳森的回答——这就是我想说的(但没有)
      【解决方案4】:

      好吧,伙计们,我试着按照你们告诉我的去做,但编译器抱怨:

      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 *'
      

      这里是 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

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

      这段代码有什么问题?很抱歉问了一些愚蠢的问题,但我只是在学习 C++ :)

      【讨论】:

      • 您没有在 dec.cpp 文件中指定类型,这就是它告诉您的。您需要在标题中有extern (type) (name);,在代码中有(type) (name) = (value);
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多