I created a global file (Globals.h) to hold my global renderer (gRenderer) and my global window (gWindow). I declared them as extern as they'll be defined inside initWindow() & initRenderer() functions under InitChess.cpp.
Some reason the linker is complaining that I have "unresolved external symbols", even though I define them in functions under InitWindow.cpp.
Errors:
Severity Code Description Project File Line Suppression State Error LNK2001 unresolved external symbol "struct SDL_Window * gWindow" (?gWindow@@3PEAUSDL_Window@@EA) Chess C:\Users\\source\repos\Chess\Chess\InitChess.obj
Severity Code Description Project File Line Suppression State Error LNK2001 unresolved external symbol "struct SDL_Renderer * gRenderer" (?gRenderer@@3PEAUSDL_Renderer@@EA) Chess C:\Users\\source\repos\Chess\Chess\InitChess.obj
Chess.cpp:
#include "SDL.h"
#undef main
#include <iostream>
#include "../include/InitChess.h"
int main()
{
InitChess* e = new InitChess;
e->initWindow();
e->initRenderer();
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s", SDL_GetError());
return 3;
}
delete e;
return 0;
}
InitChess.h:
#pragma once
#include "SDL.h"
#include "../include/Globals.h"
class InitChess {
public:
void initWindow();
void initRenderer();
~InitChess();
private:
};
InitChess.cpp:
#include "../include/InitChess.h"
void InitChess::initWindow()
{
SDL_Window* createdWindow;
createdWindow = SDL_CreateWindow(
"An SDL2 window", // window title
SDL_WINDOWPOS_UNDEFINED, // initial x position
SDL_WINDOWPOS_UNDEFINED, // initial y position
640, // width, in pixels
480, // height, in pixels
SDL_WINDOW_OPENGL // flags
);
// assign created window to global window variable in Globals.h
gWindow = createdWindow;
}
void InitChess::initRenderer()
{
SDL_Renderer* createdRenderer;
createdRenderer = SDL_CreateRenderer(gWindow, -1, 0);
// assign created render to global renderer variable in Globals.h
gRenderer = createdRenderer;
}
InitChess::~InitChess()
{
SDL_DestroyRenderer(gRenderer);
SDL_Quit();
}
Globals.h:
#pragma once
#include "SDL.h"
#ifndef GLOBALS_H
#define GLOBALS_H
extern SDL_Window* gWindow;
extern SDL_Renderer* gRenderer;
#endif
There is a difference between a declaration and a definition.
Usually writing
SDL_Window* gWindow;
is a declaration and a definition of the variable gWindow
.
Every (non-inline) variable that your program uses can have multiple declarations, but must have exactly one definition.
Putting extern
before SDL_Window* gWindow;
makes the declaration be not a definition.
Thus you still need to put a definition of gWindow
somewhere. This must appear only once in the program and therefore you cannot put the definition in a header file which may be included in multiple .cpp
files.
You need to choose one .cpp
file and put the definition SDL_Window* gWindow;
there. The definition must be at global scope, otherwise it is not referring to the same variable as the declaration extern SDL_Window* gWindow;
in Globals.h
.
In your code it seems that this file is supposed to be InitChess.cpp
, but depending on your design it may be better to create a Globals.cpp
and put the definitions there.
// assign created window to global window variable in Globals.h
gWindow = createdWindow;
This is not a definition and not even a declaration. It is just an assignment expression. A declaration for a variable starts with its type name. But as mentioned above, simply putting SDL_Window*
in front of this line will not define the global variable declared in Globals.h
. Instead it would declare and define a new local variable of the same name in the function.