Fatal error LNK1561: entry point must be defined

Started by
7 comments, last by BluePhase 10 years, 11 months ago

For some reason I have been having a hard time figuring this out. I used the source code from the Microsoft DirectX 11 Tutorial series to generate a DirectX window but I am receiving a huge list of errors while compiling it.

The tutorial required me to include these libraries:

d3d11.lib
d3dcompiler.lib
dxguid.lib
winmm.lib
comctl32.lib

but the first error I got was huge but cant seem to recreate it anymore after I removed the above include libraries.

I then reincluded them and then got the following error:

"fatal error LNK1561: entry point must be defined"

I tried everything to fix the error but nothing is working so any help at all would be appreciated.

I modified the source code a little bit into this:

Game.cpp followed by Game.h:


#include "Game.h"

int WINAPI Game::wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow )
{
    UNREFERENCED_PARAMETER( hPrevInstance );
    UNREFERENCED_PARAMETER( lpCmdLine );

    if( FAILED( InitGameWindow( hInstance, nCmdShow ) ) )
        return 0;

    if( FAILED( InitDirect3D() ) )
    {
        CleanupDevice();
        return 0;
    }

    // Main message loop
    MSG msg = {0};
    while( WM_QUIT != msg.message )
    {
        if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
        else
        {
            Render();
        }
    }

    CleanupDevice();

    return ( int )msg.wParam;
}

HRESULT Game::InitGameWindow(HINSTANCE hInstance, int cmdShow)
{
    // Register class
    WNDCLASSEX wcex;
    wcex.cbSize = sizeof( WNDCLASSEX );
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
	wcex.hIcon = LoadIcon( hInstance, ( LPCTSTR )IDI_WINLOGO );
    wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
    wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = L"Project Plexice";
    wcex.hIconSm = LoadIcon( wcex.hInstance, ( LPCTSTR )IDI_WINLOGO );
    if( !RegisterClassEx( &wcex ) )
        return E_FAIL;

    // Create window
    g_hInst = hInstance;
    RECT rc = { 0, 0, 640, 480 };
    AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );
    g_hWnd = CreateWindow( L"Project Plexice", L"Project Plexice - Development build 0.1", WS_OVERLAPPEDWINDOW,
                           CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance,
                           NULL );
    if( !g_hWnd )
        return E_FAIL;

    ShowWindow( g_hWnd, cmdShow );

     return S_OK;
}

HRESULT Game::InitDirect3D()
{
    HRESULT hr = S_OK;

    RECT rc;
    GetClientRect( g_hWnd, &rc );
    UINT width = rc.right - rc.left;
    UINT height = rc.bottom - rc.top;

    UINT createDeviceFlags = 0;
#ifdef _DEBUG
    createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

    D3D_DRIVER_TYPE driverTypes[] =
    {
        D3D_DRIVER_TYPE_HARDWARE,
        D3D_DRIVER_TYPE_WARP,
        D3D_DRIVER_TYPE_REFERENCE,
    };
    UINT numDriverTypes = ARRAYSIZE( driverTypes );

    D3D_FEATURE_LEVEL featureLevels[] =
    {
        D3D_FEATURE_LEVEL_11_0,
    };
	UINT numFeatureLevels = ARRAYSIZE( featureLevels );

    DXGI_SWAP_CHAIN_DESC sd;
    ZeroMemory( &sd, sizeof( sd ) );
    sd.BufferCount = 1;
    sd.BufferDesc.Width = width;
    sd.BufferDesc.Height = height;
    sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    sd.BufferDesc.RefreshRate.Numerator = 60;
    sd.BufferDesc.RefreshRate.Denominator = 1;
    sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    sd.OutputWindow = g_hWnd;
    sd.SampleDesc.Count = 1;
    sd.SampleDesc.Quality = 0;
    sd.Windowed = TRUE;

    for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ )
    {
        g_driverType = driverTypes[driverTypeIndex];
        hr = D3D11CreateDeviceAndSwapChain( NULL, g_driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels,
                                            D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext );
        if( SUCCEEDED( hr ) )
            break;
    }
    if( FAILED( hr ) )
        return hr;

    // Create a render target view
    ID3D11Texture2D* pBackBuffer = NULL;
    hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), ( LPVOID* )&pBackBuffer );
    if( FAILED( hr ) )
        return hr;

    hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView );
    pBackBuffer->Release();
    if( FAILED( hr ) )
        return hr;

    g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, NULL );

    // Setup the viewport
    D3D11_VIEWPORT vp;
    vp.Width = (FLOAT)width;
    vp.Height = (FLOAT)height;
    vp.MinDepth = 0.0f;
    vp.MaxDepth = 1.0f;
    vp.TopLeftX = 0;
    vp.TopLeftY = 0;
    g_pImmediateContext->RSSetViewports( 1, &vp );

    return S_OK;
}


void Game::Render()
{
    // Just clear the backbuffer
    float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; //red,green,blue,alpha
    g_pImmediateContext->ClearRenderTargetView( g_pRenderTargetView, ClearColor );
    g_pSwapChain->Present( 0, 0 );
}

LRESULT CALLBACK Game::WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
    PAINTSTRUCT ps;
    HDC hdc;

    switch( message )
    {
        case WM_PAINT:
            hdc = BeginPaint( hWnd, &ps );
            EndPaint( hWnd, &ps );
            break;

        case WM_DESTROY:
            PostQuitMessage( 0 );
            break;

        default:
            return DefWindowProc( hWnd, message, wParam, lParam );
    }

    return 0;
}

void Game::CleanupDevice()
{
    if( g_pImmediateContext ) g_pImmediateContext->ClearState();

    if( g_pRenderTargetView ) g_pRenderTargetView->Release();
    if( g_pSwapChain ) g_pSwapChain->Release();
    if( g_pImmediateContext ) g_pImmediateContext->Release();
    if( g_pd3dDevice ) g_pd3dDevice->Release();
}

#ifndef GAME_H


#include <windows.h>
//#include <windowsx.h>
#include <d3d11.h>
#include <D3DX11.h>

class Game
{
public:
	Game(HINSTANCE hInstance);
	virtual ~Game();

	int Run();

	HWND GetGameWindow() const;
	HINSTANCE GetGameInstance() const;
	float GetAspectRatio() const;

	bool Init();
	void Update(float dt);
	void Render();
	LRESULT MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
	int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow );

public:
	HRESULT InitGameWindow(HINSTANCE hInstance, int cmdShow);
	HRESULT InitDirect3D();
	void CleanupDevice();

	UINT creationFlags;

	//DirectX attributes
HINSTANCE               g_hInst;
HWND                    g_hWnd;
D3D_DRIVER_TYPE         g_driverType;
D3D_FEATURE_LEVEL       g_featureLevel;
ID3D11Device*           g_pd3dDevice;
ID3D11DeviceContext*    g_pImmediateContext;
IDXGISwapChain*         g_pSwapChain;
ID3D11RenderTargetView* g_pRenderTargetView;
};

#endif // !GAME_H

Advertisement

Where is your global WinMain function?

Where is your global WinMain function?

Isn't that in my header file? I declared wWinMain in my Game.h and used Game::wWinMain in my Game.cpp file.

Are you coming from Java? In C++ main function is global, not in a class.

Are you coming from Java? In C++ main function is global, not in a class.

Yea I am a general Java programmer trying to get into C++ game development. How could I modify my code into just keeping the main function as global? Would I need to just not derive from the class and just directly do int WINAPI wWinMain()?


// global function in .cpp, no need to put declare it in .h
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ) {
    // create Game object here and call wWinMain method
}


// global function in .cpp, no need to put declare it in .h
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ) {
    // create Game object here and call wWinMain method
}

It seemed to work but now I am getting new errors:


1>Game.obj : error LNK2019: unresolved external symbol "public: __thiscall Game::Game(void)" (??0Game@@QAE@XZ) referenced in function _wWinMain@16
1>Game.obj : error LNK2019: unresolved external symbol "public: __thiscall Game::Game(struct HINSTANCE__ *)" (??0Game@@QAE@PAUHINSTANCE__@@@Z) referenced in function "void __cdecl `dynamic initializer for 'ApplicationHandle''(void)" (??__EApplicationHandle@@YAXXZ)
1>Game.obj : error LNK2019: unresolved external symbol "public: virtual __thiscall Game::~Game(void)" (??1Game@@UAE@XZ) referenced in function "void __cdecl `dynamic atexit destructor for 'ApplicationHandle''(void)" (??__FApplicationHandle@@YAXXZ)

I'm not sure why this is happening either.

You declared constructor and destructor in .h file


	Game(HINSTANCE hInstance);
	virtual ~Game();

but didn't define them in .cpp file.

Thanks so much! Finally fixed all the errors. Thanks again ;)

This topic is closed to new replies.

Advertisement