C ++ / SDL проблема двойного включения - PullRequest
0 голосов
/ 03 ноября 2010

Я получаю эту ошибку от компилятора:

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

Может кто-нибудь помочь? Заранее спасибо и хорошего дня:)

Ответы [ 4 ]

3 голосов
/ 03 ноября 2010

Вы определяете и инициализируете переменные в заголовке.

Вы должны просто объявить их в заголовке (dec.h) без каких-либо инициализаторов:

extern int g_win_flags;
extern SDL_Surface *g_screen;

Затем определить их один раз водин файл - предположительно dec.cpp - с инициализацией.

Как и раньше, вы определяли их в каждом исходном файле, который включал «dec.h», а затем запускали нарушение правила ODR - One Definition Rule.

2 голосов
/ 03 ноября 2010

в декабре. Вы хотите

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;

Общее правило: «Ничто в заголовочном файле не должно занимать места на выходе компилятора». (Есть исключения из этого, очевидно)

На практике это означает, что объявления внешних переменных хороши, как и объявления функций, но не определения.

0 голосов
/ 03 ноября 2010

Ну, я пытался сделать то, что вы сказали мне, ребята, но компилятор жалуется:

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

Вот дек.ч

#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 ++:)

0 голосов
/ 03 ноября 2010

Вы включили файлы в два разных исходных файла (init.cpp и main.cpp), которые определяют экземпляры переменных.

Вам нужен способ быть уверенным, что они "externed" во всех файлах, кроме одного.

...