-
Linking problem
I am getting a linking error:
FirstGame error LNK2001: unresolved external symbol "protected: static class GameEngine * GameEngine::m_pGameEngine" (?m_pGameEngine@GameEngine@@1PAV1@A)
Here is my code, can anyone help me with it
GameEngine.h
Code:
BOOL GameInitialize(HINSTANCE hInstance);
void GameStart(HWND hWindow);
void GameEnd();
void GameActivate(HWND hWindow);
void GameDeactivate(HWND hWindow);
void GamePaint(HDC hDC);
void GameCycle();
class GameEngine
{
protected:
//Member Variables
static GameEngine* m_pGameEngine;
HINSTANCE m_hInstance;
HWND m_hWindow;
TCHAR m_szWindowClass[32];
TCHAR m_szTitle[32];
WORD m_wIcon, m_wSmallIcon;
int m_iWidth, m_iHeight;
int m_iFrameDelay;
BOOL m_bSleep;
public:
GameEngine(HINSTANCE hInstance, LPTSTR szWindowClass, LPTSTR szTitle, WORD wIcon, WORD wSmallIcon,int iWidth=640, int iHeight=480);
virtual ~GameEngine();
//General Methods
static GameEngine* GetEngine(){ return m_pGameEngine; };
BOOL Initialize(int iCmdShow);
LRESULT HandleEvent(HWND hWindow, UINT msg, WPARAM wParam, LPARAM lParam);
//Accessor Methods
HINSTANCE GetInstance(){return m_hInstance;};
HWND GetWindow(){return m_hWindow;};
void SetWindow(HWND hWindow){m_hWindow=hWindow;};
LPTSTR GetTitle(){return m_szTitle;};
WORD GetIcon(){return m_wIcon;};
WORD GetSmallIcon() { return m_wSmallIcon;};
int GetWidth(){ return m_iWidth;};
int GetHeight(){ return m_iHeight;};
int GetFrameDelay(){return m_iFrameDelay;};
void SetFrameRate(int iFrameRate){m_iFrameDelay =1000/iFrameRate;};
BOOL GetSleep(){return m_bSleep;};
void SetSleep(BOOL bSleep){m_bSleep=bSleep;};
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
MSG msg;
static int iTickTrigger=0;
int iTickCount;
if(GameInitialize(hInstance))
{
//Initialize the game engine
if(!GameEngine::GetEngine()->Initialize(iCmdShow))
return false;
//Enter the main message loop
while(TRUE)
{
if(PeekMessage(&msg, NULL, 0,0,PM_REMOVE))
{
//Process the message
if(msg.message==WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
//Make sure the game engine isn't sleeping
if(!GameEngine::GetEngine()->GetSleep())
{
//Check the tick count to see if a game cycle has elapsed
iTickCount=GetTickCount();
if(iTickCount> iTickTrigger)
{
iTickTrigger=iTickCount+GameEngine::GetEngine()->GetFrameDelay();
GameCycle();
}
}
}
}
return (int)msg.wParam;
}
//End the game
GameEnd();
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWindow,UINT msg, WPARAM wParam, LPARAM lParam)
{
//Route all windows messages to the game engine
return GameEngine::GetEngine()->HandleEvent(hWindow,msg,wParam,lParam);
}
GameEngine::GameEngine(HINSTANCE hInstance, LPTSTR szWindowClass, LPTSTR szTitle, WORD wIcon, WORD wSmallIcon, int iWidth, int iHeight)
{
//Set the member variabled for the game engine
m_pGameEngine=this;
m_hInstance=hInstance;
m_hWindow=NULL;
if(lstrlen(szWindowClass)>0)
lstrcpy(m_szWindowClass, szWindowClass);
if(lstrlen(szTitle)>0)
lstrcpy(m_szTitle,szTitle);
m_wIcon=wIcon;
m_wSmallIcon=wSmallIcon;
m_iWidth=iWidth;
m_iHeight=iHeight;
m_iFrameDelay=50; //20 fps default
m_bSleep=TRUE;
}
GameEngine::~GameEngine()
{}
BOOL GameEngine::Initialize(int iCmdShow)
{
WNDCLASSEX wndclass;
//Create the window class for the main window
wndclass.cbSize=sizeof(wndclass);
wndclass.style=CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc=WndProc;
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hInstance=m_hInstance;
wndclass.hIcon=LoadIcon(m_hInstance,MAKEINTRESOURCE(GetIcon()));
wndclass.hIconSm=LoadIcon(m_hInstance,MAKEINTRESOURCE(GetSmallIcon()));
wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
wndclass.lpszMenuName=NULL;
wndclass.lpszClassName=m_szWindowClass;
//Register the window class
if(!RegisterClassEx(&wndclass))
return false;
//Calculate the window size and position based upon game size
int iWindowWidth=m_iWidth + GetSystemMetrics(SM_CXFIXEDFRAME) *2,
iWindowHeight=m_iHeight+GetSystemMetrics(SM_CYFIXEDFRAME) *2+ GetSystemMetrics(SM_CYCAPTION);
if(wndclass.lpszMenuName !=NULL)
iWindowHeight += GetSystemMetrics(SM_CYMENU);
int iXWindowPos=(GetSystemMetrics(SM_CXSCREEN)-iWindowWidth) / 2,
iYWindowPos=(GetSystemMetrics(SM_CYSCREEN)-iWindowHeight)/ 2;
//Create the window
m_hWindow=CreateWindow(m_szWindowClass,m_szTitle, WS_POPUPWINDOW | WS_CAPTION | WS_MINIMIZEBOX,iXWindowPos,iYWindowPos,iWindowWidth,iWindowHeight,NULL,NULL,m_hInstance,NULL);
if(!m_hWindow)
return false;
//Show and update the window
ShowWindow(m_hWindow,iCmdShow);
UpdateWindow(m_hWindow);
return TRUE;
}
LRESULT GameEngine::HandleEvent(HWND hWindow, UINT msg, WPARAM wParam, LPARAM lParam)
{
//Route Windows messages to game member functions
switch(msg)
{
case WM_CREATE:
//Set the game window and start game
SetWindow(hWindow);
GameStart(hWindow);
return 0;
case WM_ACTIVATE:
//Activate/deactivate the game and update the Sleep status
if(wParam != WA_INACTIVE)
{
GameActivate(hWindow);
SetSleep(FALSE);
}
else
{
GameDeactivate(hWindow);
SetSleep(TRUE);
}
return 0;
case WM_PAINT:
HDC hDC;
PAINTSTRUCT ps;
hDC=BeginPaint(hWindow,&ps);
//paint the game
GamePaint(hDC);
EndPaint(hWindow,&ps);
return 0;
case WM_DESTROY:
//End the game and exit the application
GameEnd();
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWindow,msg,wParam,lParam);
}
FirstGame.cpp
Code:
#include "FirstGame.h"
BOOL GameInitialize(HINSTANCE hInstance)
{
//Create the game engine
_pGame=new GameEngine(hInstance,TEXT("First Game"),TEXT("First Game"),IDI_ICON,IDI_ICON);
if(_pGame==NULL)
return false;
//Set the frame rate
_pGame->SetFrameRate(15);
return TRUE;
}
void GameStart(HWND hWindow)
{
//Seed the random number generator
srand(GetTickCount());
}
void GameEnd()
{
//Cleanup the game engine
delete _pGame;
}
void GameActivate(HWND hWindow)
{
HDC hDC;
RECT rect;
//Draw activiation text on game screen
GetClientRect(hWindow,&rect);
hDC=GetDC(hWindow);
DrawText(hDC,TEXT("ACTIVATED!"),-1,&rect,DT_SINGLELINE | DT_CENTER | DT_VCENTER);
ReleaseDC(hWindow,hDC);
}
void GameDeactivate(HWND hWindow)
{
HDC hDC;
RECT rect;
//Draw deactiviation text on game screen
GetClientRect(hWindow,&rect);
hDC=GetDC(hWindow);
DrawText(hDC,TEXT("DEACTIVATED!"),-1,&rect,DT_SINGLELINE | DT_CENTER | DT_VCENTER);
ReleaseDC(hWindow,hDC);
}
void GamePaint(HDC hDC)
{}
void GameCycle()
{
HDC hDC;
HWND hWindow = _pGame->GetWindow();
//Draw the skeleton icon at random positions on the game screen
hDC=GetDC(hWindow);
DrawIcon(hDC, rand() % _pGame->GetWidth(), rand() % _pGame->GetHeight(),(HICON)(WORD)GetClassLong(hWindow,GCL_HICON));
ReleaseDC(hWindow,hDC);
}
FirstGame.h
Code:
#pragma once
#include <windows.h>
#include "resource.h"
#include "GameEngine.h"
GameEngine* _pGame;
-
Static data members exist independently of any instance of a class. They exist throughout the lifetime of your program even before any of your classes are constructed and they continue to exist beyond the last class being destroyed until the end of the program. You must therefore declare an object of the type given in the error in one of your source files in order for your code to link.
Place this line in the same source file where your GameEngine member functions are defined:
Code:
GameEngine::GameEngine* m_pGameEngine;
-
error C2143: syntax error : missing ';' before '*'
error C2501: 'm_pGameEngine' : missing storage-class or type
specifiers
error C2761: '__ctor' : member function redeclaration not allowed
These are the errors I get when I add that line. all the errors are on the line I put the code.
-
My syntax was off, I think this should work:
Code:
GameEngine* GameEngine::m_pGameEngine;
-
Thank You!!! that was it. I probably should have been able to fix the syntax, but I figured you had it right, so I didn't bother, but thanks for the followups