Question

I am trying to set up a basic application at the moment and I want to use Direct3D9 as the API to draw primitive shapes. For example, I want to create a circle which will be drawn by the circle object and a triangle in the triangle object etc.

My problem is that I am getting LNK2005 errors where I am not expecting to see them. That or I have missed something very obvious because I have used this method of setting up Direct3D9 before with no problems.

Here is the actual error message I receive from the compiler (VS 2010)

1>RigidBody.obj : error LNK2005: "struct IDirect3DDevice9 * d3dDevice" (?d3dDevice@@3PAUIDirect3DDevice9@@A) already defined in Main.obj
1>RigidBody.obj : error LNK2005: "struct IDirect3D9 * d3d" (?d3d@@3PAUIDirect3D9@@A) already defined in Main.obj
1>H:\Documents\My Programs\2DPhysEngine\Debug\2DPhysEngine.exe : fatal error LNK1169: one or more multiply defined symbols found

I currently have two classes (RigidBody and Circle) although only RigidBody is used at the moment.

Headers.h

#ifndef HEADERS_H
#define HEADERS_H

#include <string>
#include <vector>
#include <windows.h>
#include <windowsx.h>
#include <vector>
#include <d3d9.h>
#include <d3dx9.h>

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

#define SCREEN_WIDTH  1920 
#define SCREEN_HEIGHT 1080

LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3dDevice;

#endif

Main.cpp

#include "Headers.h"
#include "RigidBody.h"

void initDirectX(HWND hWnd);       // Initializes Direct3D Graphics
void render();                     // Render graphics
void cleanUp();                    // Cleans everything up and releases memory
void gameSetUp();

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    HWND hWnd;
    WNDCLASSEX window;
    ZeroMemory(&window, sizeof(WNDCLASSEX));
    window.cbSize = sizeof(WNDCLASSEX);
    window.style = CS_HREDRAW | CS_VREDRAW;
    window.lpfnWndProc = WindowProc;procedure
    window.hInstance = hInstance;
    window.hCursor = LoadCursor(NULL, IDC_ARROW);
    window.lpszClassName = "Window";
    RegisterClassEx(&window);

    hWnd = CreateWindowEx(NULL,
        "Window",
        "Space Game",
        WS_EX_TOPMOST | WS_POPUP,
        0, 0,
        SCREEN_WIDTH, SCREEN_HEIGHT,
        NULL,
        NULL,
        hInstance,
        NULL);

        ShowWindow(hWnd, nCmdShow);
        initDirectX(hWnd);
        MSG msg = {0};
        gameSetUp();

/************************************** Main game loop *************************************************/

while(TRUE)
{
    if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
        if(msg.message == WM_QUIT)
            break;
    }
    else                  
    {
        render();
    }
}

/*******************************************************************************************************/

cleanUp();
return msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
    case WM_DESTROY:
        {
            PostQuitMessage(0);
            return 0;  
        } 
        break;
}
return DefWindowProc (hWnd,
    message,
    wParam,
    lParam);
}

void initDirectX(HWND hWnd)
{
    d3d = Direct3DCreate9(D3D_SDK_VERSION);
    D3DPRESENT_PARAMETERS d3dParameters;
    ZeroMemory(&d3dParameters, sizeof(d3dParameters));
    d3dParameters.Windowed = FALSE;
    d3dParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dParameters.hDeviceWindow = hWnd;
    d3dParameters.BackBufferFormat = D3DFMT_X8R8G8B8;
    d3dParameters.BackBufferWidth = SCREEN_WIDTH;
    d3dParameters.BackBufferHeight = SCREEN_HEIGHT;

    d3d->CreateDevice(D3DADAPTER_DEFAULT,
        D3DDEVTYPE_HAL,
        hWnd,
        D3DCREATE_SOFTWARE_VERTEXPROCESSING,
        &d3dParameters,
        &d3dDevice);
}

void render()
{
    d3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(10, 0, 32), 1.0f, 0);
    d3dDevice->BeginScene();
    d3dDevice->EndScene();
    d3dDevice->Present(NULL, NULL, NULL, NULL);
}

void cleanUp()
{
    d3dDevice->Release();
    d3d->Release();
}

void gameSetUp()
{
}

RigidBody.h

#include "Headers.h"

class RigidBody
{

protected:

    float velocity[1];
    float position[1];
    float mass;

public:

    virtual void initPrimitiveGraphics(); // Not implemented yet
    virtual void drawPrimitiveObject(); // Not implemented yet

};

Circle.h

#include "RigidBody.h"

class Circle : public RigidBody
{

private:

    float radius;

public:

    Circle(float objectPosition[1], float objectMass, float objectRadius);

};

The Circle and RigidBody class do also have their own .cpp file but no method (or ANY code for that matter) is implemented in these "placeholder" files yet.

So can anyone see why I cam getting this error? I am hoping for it to be a simple one but am not sure as I have set up Direct3D 9 in this way before having no issues.

What I mean when I say I have set it up in this way before is that I have put the Direct3D9 headers and pointers to LPDIRECT3DDEVICE9 and LPDIRECT3D9 in a global header file and just surrounded it using include guards. This worked for my last project and I have compared the two with no obvious difference.

I have messed around with the guard identifiers, thinking it may have been invalid or in use elsewhere and using the most unique guard identifier I could think of presented me with the same error.

When I put:

LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3dDevice;

in the Main.cpp and take it out of the Headers.h file, the project compiles fine. However, I do not want this as I want to access LPDIRECT3DDEVICE9 from within each object as this is where I intent to set up the primitive shapes.

Was it helpful?

Solution

It because you are declaring global object in Headers.h. Globals object can not be declared more than one time. (each time you include the header, they will be declared...)

you should change

LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3dDevice;

by

extern LPDIRECT3D9 d3d;
extern LPDIRECT3DDEVICE9 d3dDevice;

in you Headers.h and put the declaration of the objects in Main.cpp for example :

// main.cpp
LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3dDevice;

OTHER TIPS

Change Headers.h to

extern LPDIRECT3D9 d3d;
extern LPDIRECT3DDEVICE9 d3dDevice;

And put

LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3dDevice;

in only one .cpp file (Main.cpp will do)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top