Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 645823
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 13, 20262026-05-13T21:32:42+00:00 2026-05-13T21:32:42+00:00

Can you call a function that has no body but is declared in the

  • 0

Can you call a function that has no body but is declared in the header in your code?? Please read below for my situation.

I am learning c++ so if my terminology is off then you know why. Any how, I am reading this book called “Advanced 2D Game Development” so if anyone’s read the book then maybe they can help me out. In c++ he set 4 extern functions in Advanced2D.h

extern bool game_preload();
extern bool game_init(HWND);
extern void game_update();
extern void game_end();

Later on down the line he calls on them several time’s in a class but never gives them a body. What he is eventually trying to do with all the code is compile it into lib file so other projects could include it and actually use those 4 methods.

He wanted me to go to the solutions properties/General/Output Directory and add this in both the Release and Debug Configuration

$(ProjectDir)..\lib\Advance2D.lib // It didn't work. Still added the libs at default location

Only to use those methods above in another project like this . This is when declarative methods get their bodies.

#include <iostream>
#include "..\Engine\Advanced2D.h"
bool game_preload()
{
     //display engine version in a message box
     g_engine->message(g_engine->getVersionText(), "TEST ENGINE");
     //return fail to terminate the engine
     return false;
}

bool game_init(HWND hwnd) { return 0;}
void game_update() {}
void game_end() {}

The only problem now is that I receive a linker error

1>winmain.obj : error LNK2019: unresolved external symbol "bool __cdecl game_preload(void)" (?game_preload@@YA_NXZ) referenced in function _WinMain@16
1>c:\Engine\msvc8\Advance2D\Advance2D\..\lib\Advance2D.lib\Advance2D.exe : fatal error LNK1120: 1 unresolved externals

If I don’t comment out those methods being used in the first project then the project never gets compiled ?

The guy insist that I shouldn’t receive any linker errors at the time of compiling it. And I quote the following

Assuming you have typed the code into
the specified files without any
mistakes, you should be able to
compile the engine project. There
should be no dependencies for the
engine because the compiler assumes
that you will provide the needed libs
at link time (when you create an
executable using the engine’s lib).
This is a rather complex issue that
we’ll examine again over the next
several chapters as we enhance the
engine with new modules and
functionality. You should not see any
linker errors, only compiler errors if
you have made a mistake while typing
in the code.

the following is advanced2D header

// Advanced2D Engine
// Main header file
#ifndef _ADVANCED2D_H
#define _ADVANCED2D_H 1
#include <iostream>
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <dxerr.h>
#include "Timer.h"
#define VERSION_MAJOR 1
#define VERSION_MINOR 0
#define REVISION 0

#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
#pragma comment(lib, "winmm.lib")

//external variables and functions
extern bool gameover;
extern bool game_preload();
extern bool game_init(HWND);
extern void game_update();
extern void game_end();

namespace Advanced2D
{
    class Engine {
        private:
            int p_versionMajor, p_versionMinor, p_revision;
            HWND p_windowHandle;
            LPDIRECT3D9 p_d3d;
            LPDIRECT3DDEVICE9 p_device;
            LPDIRECT3DSURFACE9 p_backbuffer;
            LPD3DXSPRITE p_sprite_handler;
            std::string p_apptitle;
            bool p_fullscreen;
            int p_screenwidth;
            int p_screenheight;
            int p_colordepth;
            bool p_pauseMode;
            D3DCOLOR p_ambientColor;
            bool p_maximizeProcessor;
            Timer p_coreTimer;
            long p_frameCount_core;
            long p_frameRate_core;
            Timer p_realTimer;
            long p_frameCount_real;
            long p_frameRate_real;
        public:
            Engine();
            virtual ~Engine();
            int Init(int width, int height, int colordepth, bool fullscreen);
            void Close();
            void Update();
            void message(std::string message, std::string title = "ADVANCED 2D");
            void fatalerror(std::string message, std::string title = "FATAL ERROR");
            void Shutdown();
            void ClearScene(D3DCOLOR color);
            void SetDefaultMaterial();
            void SetAmbient(D3DCOLOR colorvalue);
            int RenderStart();
            int RenderStop();
            int Release();
            //accessor/mutator functions expose the private variables
            bool isPaused() { return this->p_pauseMode; }
            void setPaused(bool value) { this->p_pauseMode = value; }
            LPDIRECT3DDEVICE9 getDevice() { return this->p_device; }
            LPDIRECT3DSURFACE9 getBackBuffer() { return this->p_backbuffer; }
            LPD3DXSPRITE getSpriteHandler() { return this->p_sprite_handler; }
            void setWindowHandle(HWND hwnd) { this->p_windowHandle = hwnd; }
            HWND getWindowHandle() { return this->p_windowHandle; }
            std::string getAppTitle() { return this->p_apptitle; }
            void setAppTitle(std::string value) { this->p_apptitle = value; }
            int getVersionMajor() { return this->p_versionMajor; }
            int getVersionMinor() { return this->p_versionMinor; }
            int getRevision() { return this->p_revision; }
            std::string getVersionText();
            long getFrameRate_core() { return this->p_frameRate_core; };
            long getFrameRate_real() { return this->p_frameRate_real; };
            int getScreenWidth() { return this->p_screenwidth; }
            void setScreenWidth(int value) { this->p_screenwidth = value; }
            int getScreenHeight() { return this->p_screenheight; }
            void setScreenHeight(int value) { this->p_screenheight = value; }
            int getColorDepth() { return this->p_colordepth; }
            void setColorDepth(int value) { this->p_colordepth = value; }
            bool getFullscreen() { return this->p_fullscreen; }
            void setFullscreen(bool value) { this->p_fullscreen = value; }
            bool getMaximizeProcessor() { return this->p_maximizeProcessor; }
            void setMaximizeProcessor(bool value) { this->p_maximizeProcessor = value;}
    }; //class
}; //namespace
//define the global engine object (visible everywhere!)
extern Advanced2D::Engine *g_engine;
#endif

Advanced2d class

// Advanced2D Engine
// Main source code file
//includes
#include "Advanced2D.h"
#include <cstdlib>
#include <ctime>
#include <string>
#include <sstream>
#include <list>
#include "winmain.h"

namespace Advanced2D
{
    Engine::Engine()
    {
        srand((unsigned int)time(NULL));
        p_maximizeProcessor = false;
        p_frameCount_core = 0;
        p_frameRate_core = 0;
        p_frameCount_real = 0;
        p_frameRate_real = 0;
        p_ambientColor = D3DCOLOR_RGBA(255,255,255, 0);
        p_windowHandle = 0;
        p_pauseMode = false;
        p_versionMajor = VERSION_MAJOR;
        p_versionMinor = VERSION_MINOR;
        p_revision = REVISION;
        //set default values
        this->setAppTitle("Advanced2D");
        this->setScreenWidth(640);
        this->setScreenHeight(480);
        this->setColorDepth(32);
        this->setFullscreen(false);
        //window handle must be set later on for DirectX!
        this->setWindowHandle(0);
    }

    Engine::~Engine()
    {
        if (this->p_device) this->p_device->Release();
        if (this->p_d3d) this->p_d3d->Release();
    }

    std::string Engine::getVersionText()
    {
        std::ostringstream s;
        s << "Advanced2D Engine v" << p_versionMajor << "." << p_versionMinor
        << "." << p_revision;
        return s.str();
    }

    void Engine::message(std::string message, std::string title)
    {
        MessageBox(0, message.c_str(), title.c_str(), 0);
    }

    void Engine::fatalerror(std::string message, std::string title)
    {
        this->message(message,title);
        Shutdown();
    }

    int Engine::Init(int width, int height, int colordepth, bool fullscreen)
    {
        //initialize Direct3D

        this->p_d3d = Direct3DCreate9(D3D_SDK_VERSION);

        if (this->p_d3d == NULL) {
            return 0;
        }

        //get system desktop color depth
        D3DDISPLAYMODE dm;
        this->p_d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &dm);

        //set configuration options for Direct3D
        D3DPRESENT_PARAMETERS d3dpp;
        ZeroMemory(&d3dpp, sizeof(d3dpp));
        d3dpp.Windowed = (!fullscreen);
        d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
        d3dpp.EnableAutoDepthStencil = TRUE;
        d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
        d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
        d3dpp.BackBufferFormat = dm.Format;
        d3dpp.BackBufferCount = 1;
        d3dpp.BackBufferWidth = width;
        d3dpp.BackBufferHeight = height;
        d3dpp.hDeviceWindow = p_windowHandle;

        //create Direct3D device
        this->p_d3d->CreateDevice(
        D3DADAPTER_DEFAULT,
        D3DDEVTYPE_HAL,
        this->p_windowHandle,
        D3DCREATE_HARDWARE_VERTEXPROCESSING,
        &d3dpp,
        &this->p_device);
        if (this->p_device == NULL) return 0;

        //clear the backbuffer to black
        this->ClearScene(D3DCOLOR_XRGB(0,0,0));

        //create pointer to the back buffer
        this->p_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &this->p_backbuffer);

        //use ambient lighting and z-buffering
        this->p_device->SetRenderState(D3DRS_ZENABLE, TRUE);
        this->p_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
        this->SetAmbient(this->p_ambientColor);

        //initialize 2D renderer
        HRESULT result = D3DXCreateSprite(this->p_device, &this->p_sprite_handler);
        if (result != D3D_OK) return 0;
        //call game initialization extern function
        //if (!game_init(this->getWindowHandle())) return 0;
        //set a default material
        SetDefaultMaterial();
        return 1;
    }


    void Engine::SetDefaultMaterial()
    {
        D3DMATERIAL9 mat;
        memset(&mat, 0, sizeof(mat));
        mat.Diffuse.r = 1.0f;
        mat.Diffuse.g = 1.0f;
        mat.Diffuse.b = 1.0f;
        mat.Diffuse.a = 1.0f;
        p_device->SetMaterial(&mat);
    }

    void Engine::ClearScene(D3DCOLOR color)
    {
        this->p_device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
        color, 1.0f, 0);
    }

    void Engine::SetAmbient(D3DCOLOR colorvalue)
    {
        this->p_ambientColor = colorvalue;
        this->p_device->SetRenderState(D3DRS_AMBIENT, this->p_ambientColor);
    }
    int Engine::RenderStart()
    {
        if (!this->p_device) return 0;
        if (this->p_device->BeginScene() != D3D_OK) return 0;
        return 1;
    }
    int Engine::RenderStop()
    {
        if (!this->p_device) return 0;
        if (this->p_device->EndScene() != D3D_OK) return 0;
        if (p_device->Present(NULL, NULL, NULL, NULL) != D3D_OK) return 0;
        return 1;
    }

    void Engine::Shutdown()
    {
        gameover = true;
    }

    void Engine::Update()
    {
        static Timer timedUpdate;
        //calculate core framerate
        p_frameCount_core++;
        if (p_coreTimer.stopwatch(999)) {
        p_frameRate_core = p_frameCount_core;
        p_frameCount_core = 0;
        }
        //fast update with no timing
        game_update();

        //update with 60fps timing
        if (!timedUpdate.stopwatch(14)) {
            if (!this->getMaximizeProcessor())
            {
                Sleep(1);
            }
        }
        else {
            //calculate real framerate
            p_frameCount_real++;

            if (p_realTimer.stopwatch(999)) {
                p_frameRate_real = p_frameCount_real;
                p_frameCount_real = 0;
            }
            //begin rendering
            this->RenderStart();
            //done rendering
            this->RenderStop();
        }
    }
    void Engine::Close()
    {
        game_end();
    }
} //namespace

And here is the WinMain

#include <sstream>
#include "winmain.h"
#include "Advanced2D.h"
//macro to read the key states
#define KEY_DOWN(vk) ((GetAsyncKeyState(vk) & 0x8000)?1:0)
HINSTANCE g_hInstance;
HWND g_hWnd;
int g_nCmdShow;
//declare global engine object
Advanced2D::Engine *g_engine;
bool gameover;


//window event callback function
LRESULT WINAPI WinProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
    case WM_QUIT:
    case WM_CLOSE:
    case WM_DESTROY:
    gameover = true;
    break;
    }
    return DefWindowProc( hWnd, msg, wParam, lParam );
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int
nCmdShow)
{
    MSG msg;
    srand((unsigned int)time(NULL));
    g_hInstance = hInstance;
    g_nCmdShow = nCmdShow;
    DWORD dwStyle, dwExStyle;
    RECT windowRect;
    /**
    * Create engine object first!
    **/
    g_engine = new Advanced2D::Engine();
    //let main program have a crack at things before window is created
    if (!game_preload()) {
        MessageBox(g_hWnd, "Error in game preload!", "Error", MB_OK);
        return 0;
    }
    //get window caption string from engine
    char title[255];
    sprintf_s(title, "%s", g_engine->getAppTitle().c_str());
    //set window dimensions
    windowRect.left = (long)0;
    windowRect.right = (long)g_engine->getScreenWidth();
    windowRect.top = (long)0;
    windowRect.bottom = (long)g_engine->getScreenHeight();
    //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 = NULL;
    wc.lpszMenuName = NULL;
    wc.lpszClassName = title;
    wc.hIconSm = NULL;
    //set up the window with the class info
    RegisterClassEx(&wc);
    //set up the screen in windowed or fullscreen mode?
    if (g_engine->getFullscreen())
    {
        DEVMODE dm;
        memset(&dm, 0, sizeof(dm));
        dm.dmSize = sizeof(dm);
        dm.dmPelsWidth = g_engine->getScreenWidth();
        dm.dmPelsHeight = g_engine->getScreenHeight();
        dm.dmBitsPerPel = g_engine->getColorDepth();
        dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
        if (ChangeDisplaySettings(&dm, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) {
        MessageBox(NULL, "Display mode failed", NULL, MB_OK);
        g_engine->setFullscreen(false);
        }
        dwStyle = WS_POPUP;
        dwExStyle = WS_EX_APPWINDOW;
        ShowCursor(FALSE);
        }
        else {
        dwStyle = WS_OVERLAPPEDWINDOW;
        dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
        }
        //adjust window to true requested size
        AdjustWindowRectEx(&windowRect, dwStyle, FALSE, dwExStyle);
        //create the program window
        g_hWnd = CreateWindowEx( 0,
        title, //window class
        title, //title bar
        dwStyle | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
        0, 0, //x,y coordinate
        windowRect.right - windowRect.left, //width of the window
        windowRect.bottom - windowRect.top, //height of the window
        0, //parent window
        0, //menu
        g_hInstance, //application instance
        0); //window parameters
        //was there an error creating the window?
        if (!g_hWnd) {
        MessageBox(g_hWnd, "Error creating program window!", "Error", MB_OK);
        return 0;
    }
    //display the window
    ShowWindow(g_hWnd, g_nCmdShow);
    UpdateWindow(g_hWnd);
    //initialize the engine
    g_engine->setWindowHandle(g_hWnd);
    if (!g_engine->Init(g_engine->getScreenWidth(), g_engine->getScreenHeight(),
    g_engine->getColorDepth(), g_engine->getFullscreen())) {
    MessageBox(g_hWnd, "Error initializing the engine", "Error", MB_OK);
    return 0;
    }
    // main message loop
    gameover = false;
    while (!gameover)
    {
        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        g_engine->Update();
    }

    if (g_engine->getFullscreen()) {
        ShowCursor(TRUE);
    }
    g_engine->Close();
    delete g_engine;
    return 1;
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-13T21:32:42+00:00Added an answer on May 13, 2026 at 9:32 pm

    The extern keyword specifies that the function will be implemented in a compilation object external to the one you’re in – usually via a lib or other object. If you were to declare a variable in global scope in one cpp file (outside any function body) you can only reference it using external {variable declaration} in another cpp file – so that the compiler knows not to expect the function/variable be defined but know it exists.

    What’s happening here by the sounds of things is that the object you are linking to is not actually being linked in – it should be. The above answer tells you how to – I’m not fast enough! From your question it seems like you have the source to this second project and may possibly need to built it yourself – I don’t know, of course, but if the .lib doesn’t exist then you will need to.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 354k
  • Answers 354k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer You need to do this through VBScript and load in… May 14, 2026 at 7:52 am
  • Editorial Team
    Editorial Team added an answer EDIT: I tried to clarify I bit more ... 1.… May 14, 2026 at 7:52 am
  • Editorial Team
    Editorial Team added an answer Read each line, stick the contents of the line into… May 14, 2026 at 7:52 am

Related Questions

I know that an interface does not have a body, just a method definition.
This is rather interesting, I think. Consider following code, both the window.onload and body
From time to time you hear stories that are meant to illustrate how good
Sadly, I have a legacy PHP4 system that I continuously need to add features
I need to write a delegate function that can 'wrap' some while/try/catch code around

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.