Archived

This topic is now archived and is closed to further replies.

Prime

My foolish globals and header files

Recommended Posts

Hi, It has been a long time since I have done C, so please forgive my simple question. I am getting the following linker error in VC++6: Compiling... window.cpp main.cpp Linking... window.obj : error LNK2005: "struct HWND__ * windowHandle" (?windowHandle@@3PAUHWND__@@A) already defined in main.obj The way my code is structured is that I have a main.cpp that contains my WinMain function, and I have a window.h file that contains my "window" function prototypes and my global declaration of HWND windowHandle (which is giving me the problem). window.h is included in both window.cpp and main.cpp. I assume this is giving me the problem. Can some kind soul explain how I can set up my files to that I do not get this problem? I want to keep HWND windowHandle global so it is visible to both window.cpp and main.cpp. Thanks so much for any help. I''ll include my code below in case it helps... window.h // include files #ifndef FLAG #define FLAG #include #include #define WIN32_LEAN_AND_MEAN // globals HWND windowHandle; // prototypes bool createWindow(HINSTANCE hInstance); void showWindow(int iShowCmd); LRESULT CALLBACK messageHandler(HWND wHandle, UINT message, WPARAM wParam, LPARAM lParam); #endif window.cpp #include "window.h" bool createWindow(HINSTANCE hInstance) { WNDCLASSEX wndClass; wndClass.cbSize = sizeof(WNDCLASSEX); wndClass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wndClass.lpfnWndProc = messageHandler; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 0; wndClass.hInstance = hInstance; wndClass.hIcon = LoadIcon(NULL, IDI_WINLOGO); wndClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO); wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); wndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wndClass.lpszMenuName = "MAIN_MENU"; wndClass.lpszClassName = "Game Window"; // register the window class if(!RegisterClassEx(&wndClass)) { MessageBox(NULL, "Unable to register window class", "Game Window", MB_ICONERROR); return false; } // create the window if(!(windowHandle = CreateWindowEx(NULL, "Game Window", "Game Window", WS_OVERLAPPEDWINDOW CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, 0))) { MessageBox(NULL, "Unable to create window", "Game Window", MB_ICONERROR); return false; } return true; } // makes the window visible void showWindow(int iShowCmd) { if(windowHandle != NULL) { ShowWindow(windowHandle, iShowCmd); UpdateWindow(windowHandle); } } LRESULT CALLBACK messageHandler(HWND wHandle, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_CREATE: { //initialize game return 0; } case WM_DESTROY: { PostQuitMessage(0); return 0; } } return DefWindowProc(wHandle, message, wParam, lParam); } main.cpp #include "window.h" int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int iShowCmd) { createWindow(hInstance); showWindow(iShowCmd); return 0; }

Share this post


Link to post
Share on other sites
In the .h file type the following
extern HWND windowHandle;
then in the .cpp type
HWND windowHandle;
This will allow windowHandle to be global in the project.
Just include the file with extern wherever you need the variable.



Edited by - Graham on June 5, 2001 11:18:48 PM

Share this post


Link to post
Share on other sites
You can''t put global variables in header files...

well, you can, as long as you include the header in only ONE source file... but thats not what headers are for.

anyway, put the global in which ever source file you feel is best, and then put extern in front of the global you have in your header file.

extern tells a source file that the variable has already been created somewhere else and that its ok to use it without doing anything.

Share this post


Link to post
Share on other sites
Credit Teej with this little gem:

In your header file(s), do the following:
  
#ifndef GLOBALS_OWNERSHIP
extern
#end if

struct {
// declare all the gloabl variables here

} G;


You can then place the line "#define GLOBALS_OWNERSHIP" in whichever implementation (.cpp) file you want to "own" the gloabls before you include the header ; all other files that include the header will declare the gloabl structure as extern. As an added bonus, all your gloabl variables are collected in a single object (G), and accessible as G.windowHandle, for example.

Thanks Teej!

Share this post


Link to post
Share on other sites
Hey,

Thanks everyone for your help! That solved my problem, and I have gained another piece of knowledge. I wish good karma on all of you

Prime

Share this post


Link to post
Share on other sites