C++ compile errors when copied from a book

Started by
8 comments, last by Spectralist 16 years, 4 months ago
Im a C++ programmer and i bought a book "Beginning Game Programming" by Jonathan S. Harbour. Its on how to make a game and one of the source files in the book is how to make a Game Loop so i coppied his source from the book (off of the cd) and pasted it in my dev-C++ compiler.This is the source: // Beginning Game Programming // Chapter 4 // GameLoop project #include <windows.h> #include <winuser.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #define APPTITLE "Game Loop" //function prototypes LRESULT CALLBACK WinProc(HWND,UINT,WPARAM,LPARAM); ATOM MyRegisterClass(HINSTANCE); BOOL InitInstance(HINSTANCE,int); void DrawBitmap(HDC,char*,int,int); void Game_Init(); void Game_Run(); void Game_End(); //local variables HWND global_hwnd; HDC global_hdc; //the window event callback function LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { global_hwnd = hWnd; global_hdc = GetDC(hWnd); switch (message) { case WM_DESTROY: Game_End(); PostQuitMessage(0); break; } return DefWindowProc(hWnd, message, wParam, lParam); } //helper function to set up the window properties ATOM MyRegisterClass(HINSTANCE hInstance) { //create the window class structure WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); //fill the struct with info wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = (WNDPROC)WinProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = NULL; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = APPTITLE; wc.hIconSm = NULL; //set up the window with the class info return RegisterClassEx(&wc); } //helper function to create the window and refresh it BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; //create a new window hWnd = CreateWindow( APPTITLE, //window class APPTITLE, //title bar WS_OVERLAPPEDWINDOW, //window style CW_USEDEFAULT, //x position of window CW_USEDEFAULT, //y position of window 500, //width of the window 400, //height of the window NULL, //parent window NULL, //menu hInstance, //application instance NULL); //window parameters //was there an error creating the window? if (!hWnd) return FALSE; //display the window ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } //entry point for a Windows program int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { int done = 0; MSG msg; // register the class MyRegisterClass(hInstance); // initialize application if (!InitInstance (hInstance, nCmdShow)) return FALSE; //initialize the game Game_Init(); // main message loop while (!done) { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { //look for quit message if (msg.message == WM_QUIT) done = 1; //decode and pass messages on to WndProc TranslateMessage(&msg); DispatchMessage(&msg); } //process game loop Game_Run(); } return msg.wParam; } void DrawBitmap(HDC hdcDest, char *filename, int x, int y) { HBITMAP image; BITMAP bm; HDC hdcMem; //load the bitmap image image = (void*)LoadImage(0,"c.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE); //read the bitmap's properties GetObject(image, sizeof(BITMAP), &bm); //create a device context for the bitmap hdcMem = CreateCompatibleDC(global_hdc); SelectObject(hdcMem, image); //draw the bitmap to the window (bit block transfer) BitBlt( global_hdc, //destination device context x, y, //x,y location on destination bm.bmWidth, bm.bmHeight, //width,height of source bitmap hdcMem, //source bitmap device context 0, 0, //start x,y on source bitmap SRCCOPY); //blit method //delete the device context and bitmap DeleteDC(hdcMem); DeleteObject((HBITMAP)image); } void Game_Init() { //initialize the game... //load bitmaps, meshes, textures, sounds, etc. srand(time(NULL)); } void Game_Run() { //this is called once every frame //do not include your own loop here! int x = 0, y = 0; RECT rect; GetClientRect(global_hwnd, &rect); if (rect.right > 0) { x = rand() % (rect.right - rect.left); y = rand() % (rect.bottom - rect.top); DrawBitmap(global_hdc, "c.bmp", x, y); } } void Game_End() { } The problem is, i get three errors when compiling this code: (error 1) C:\Dev-Cpp\winmain.c In function `void DrawBitmap(HDC__*, char*, int, int)': (error 2) 148 C:\Dev-Cpp\winmain.c invalid conversion from `void*' to `HBITMAP__*' (error 3) C:\Dev-Cpp\Makefile.win [Build Error] [winmain.o] Error 1 Iv researched through the forums and found that a person had an error close to mine and they replaced one of the functions with this: image = (HBITMAP) LoadImage (0, "c.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); however when i replaced it, it gave me one build error and plenty of linker errors.I dont know what to do here, any help would be greatly appreciated.
Advertisement
change this:

image = (void*)LoadImage(0,"c.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);

to this:

image = (HBITMAP)LoadImage(0,"c.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);

The reason is that (standard compliant) C++ doesn't allow implicit conversion from void* to any other pointer type.
Also, and this is just a nit pick really, I'm not willing to read your code if it's as long as it is and there's no indentation. Encapsulate your code in [ source lang="cpp" ]
[ /source ] (without the spaces).

// Beginning Game Programming// Chapter 4// GameLoop project#include <windows.h>#include <winuser.h>#include <stdio.h>#include <stdlib.h>#include <time.h>#define APPTITLE "Game Loop"//function prototypesLRESULT CALLBACK WinProc(HWND,UINT,WPARAM,LPARAM);ATOM MyRegisterClass(HINSTANCE);BOOL InitInstance(HINSTANCE,int);void DrawBitmap(HDC,char*,int,int);void Game_Init();void Game_Run();void Game_End();//local variablesHWND global_hwnd;HDC global_hdc;//the window event callback functionLRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){    global_hwnd = hWnd;    global_hdc = GetDC(hWnd);    switch (message)    {        case WM_DESTROY:        Game_End();        PostQuitMessage(0);        break;    }    return DefWindowProc(hWnd, message, wParam, lParam);}//helper function to set up the window propertiesATOM MyRegisterClass(HINSTANCE hInstance){    //create the window class structure    WNDCLASSEX wc;    wc.cbSize = sizeof(WNDCLASSEX);    //fill the struct with info    wc.style = CS_HREDRAW | CS_VREDRAW;    wc.lpfnWndProc = (WNDPROC)WinProc;    wc.cbClsExtra = 0;    wc.cbWndExtra = 0;    wc.hInstance = hInstance;    wc.hIcon = NULL;    wc.hCursor = LoadCursor(NULL, IDC_ARROW);    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);    wc.lpszMenuName = NULL;    wc.lpszClassName = APPTITLE;    wc.hIconSm = NULL;    //set up the window with the class info    return RegisterClassEx(&wc);}//helper function to create the window and refresh itBOOL InitInstance(HINSTANCE hInstance, int nCmdShow){    HWND hWnd;    //create a new window    hWnd = CreateWindow(                        APPTITLE, //window class                        APPTITLE, //title bar                        WS_OVERLAPPEDWINDOW, //window style                        CW_USEDEFAULT, //x position of window                        CW_USEDEFAULT, //y position of window                        500, //width of the window                        400, //height of the window                        NULL, //parent window                        NULL, //menu                        hInstance, //application instance                        NULL); //window parameters    //was there an error creating the window?    if (!hWnd)    return FALSE;    //display the window    ShowWindow(hWnd, nCmdShow);    UpdateWindow(hWnd);    return TRUE;}//entry point for a Windows programint WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){    int done = 0;    MSG msg;    // register the class    MyRegisterClass(hInstance);    // initialize application    if (!InitInstance (hInstance, nCmdShow))        return FALSE;    //initialize the game    Game_Init();    // main message loop    while (!done)    {        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))        {            //look for quit message            if (msg.message == WM_QUIT)                done = 1;            //decode and pass messages on to WndProc            TranslateMessage(&msg);            DispatchMessage(&msg);        }        //process game loop        Game_Run();    }        return msg.wParam;}void DrawBitmap(HDC hdcDest, char *filename, int x, int y){    HBITMAP image;    BITMAP bm;    HDC hdcMem;    //load the bitmap image    image = (void*)LoadImage(0,"c.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);    //read the bitmap's properties    GetObject(image, sizeof(BITMAP), &bm);    //create a device context for the bitmap    hdcMem = CreateCompatibleDC(global_hdc);    SelectObject(hdcMem, image);    //draw the bitmap to the window (bit block transfer)    BitBlt(            global_hdc, //destination device context            x, y, //x,y location on destination            bm.bmWidth, bm.bmHeight, //width,height of source bitmap            hdcMem, //source bitmap device context            0, 0, //start x,y on source bitmap            SRCCOPY); //blit method    //delete the device context and bitmap    DeleteDC(hdcMem);    DeleteObject((HBITMAP)image);}void Game_Init(){    //initialize the game...    //load bitmaps, meshes, textures, sounds, etc.    srand(time(NULL));}void Game_Run(){    //this is called once every frame    //do not include your own loop here!    int x = 0, y = 0;    RECT rect;    GetClientRect(global_hwnd, &rect);    if (rect.right > 0)    {        x = rand() % (rect.right - rect.left);        y = rand() % (rect.bottom - rect.top);        DrawBitmap(global_hdc, "c.bmp", x, y);    }}void Game_End(){}


Looks nicer, don't it?
Quote:Original post by sniperwolf50
it gave me one build error and plenty of linker errors.

It really helps if you post those error messages.
Quote:Original post by sniperwolf50

Iv researched through the forums and found that a person had an error close to mine and they replaced one of the functions with this:

image = (HBITMAP) LoadImage (0, "c.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

however when i replaced it, it gave me one build error and plenty of linker errors.I dont know what to do here, any help would be greatly appreciated.


ya i did change the image peramiter, however i did get linker errors, and one build error. As requested here are the errors:

[Linker error] undefined reference to `GetStockObject@4'
[Linker error] undefined reference to `GetObjectA@12'
[Linker error] undefined reference to `CreateCompatibleDC@4'
[Linker error] undefined reference to `SelectObject@8'
[Linker error] undefined reference to `BitBlt@36'
[Linker error] undefined reference to `DeleteDC@4'
[Linker error] undefined reference to `DeleteObject@4'
ld returned 1 exit status
C:\Dev-Cpp\Makefile.win [Build Error] [GameLoop.exe] Error 1

those were the linker and other errors i recieved. Thank you all for your input it is much appreciated.

P.S: yes, the code does look much nicer when arranged in that window, thank you, ill have to remember to do that.
You probably need to include Gdi32.lib in the linker command line of your make-file.

Out of curiousity, what are you building with?
I will have to encourage not to use Dev-C++. Dev-C++ is outdated, and has not been updated for awhile.

I highly encourage using MSVC++ 2005 instead. Its free, and includes a nice and powerful IDE and debugger.

Either way, you will need to link with gdi32.lib, as previously mentioned, to resolve those linker errors.
ok, not to be a pain in the butt here, but im really new to C++ and i dont have all of the terminallogy down just yet. I dont know how to use linker's, im guessing a linker is like a pointer right but i dont know how to inlcude that line you guys were mentioning? Also i had originally been programming with M$ visual C++ however the problem i found with it, is that it will not recognize the windows.h library so i dumped it and went with the dev C++ compiler...Also what do u mean out of date, have you checked lately because i just downloaded a new beta 4.9.9.2 and i like it. Dont get me wrong, as far as easy user friendly interface i have to hand it to M$'s compiler there, but if it cant allow me to include that windows.h library then its crap to me.btw im not trying to create a flame war here between compilers, just saying that so far im sticking with dev C++ becasue it works for me and the M$ version doesnt. Also what did you mean by "what am i building with"?
Linking is part of compilation: C++ is compiled to object code (lots of .o, .obj files) which are then linked together to create an executable. The linker essentially resolves function calls. Hit google for a complete explanation!

The compiler is happy because everything is defined because you have the right headers included but the linker is not because the actual implementation of those defined functions cannot be found. Implementations are stored in .lib\.dll library files and you are missing a reference to a specific one - gdi32.lib.

To fix your problem you need to tell the linker where this library is. I don't know dev-cpp but you need to find where you can add a reference to .lib files e.g. on a "Link" configuration page and a setting called "Additional Libraries" or some such. Try the help for your tool.
I think you might be trying to compile it as a console application.

Go to Project->Project Options(alt-p) In the general tab you should see 'Type' with the options:
Win32 GUI
Win32 Console
Win32 Static Lib
Win32 DLL

You'll need it to be set to Win32 GUI for this application.

This topic is closed to new replies.

Advertisement