使用Direct3D9的LNK2005错误

时间:2013-07-08 20:49:47

标签: c++ direct3d9 lnk2005

我正在尝试设置一个基本的应用程序,我想使用Direct3D9作为绘制原始形状的API。例如,我想创建一个圆圈,它将由圆形对象和三角形对象中的三角形等绘制。

我的问题是我得到了LNK2005错误,我不希望看到它们。那个或者我错过了一些非常明显的东西,因为我之前使用过这种设置Direct3D9的方法没有问题。

以下是我从编译器(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

我目前有两个类(RigidBody和Circle),虽然目前只使用RigidBody。

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);

};

Circle和RigidBody类也有自己的.cpp文件,但在这些“占位符”文件中没有实现任何方法(或任何代码)。

所以有人能看出为什么我会收到这个错误吗?我希望它是一个简单的但我不确定,因为我在没有问题之前以这种方式设置了Direct3D 9。

当我说我之前以这种方式设置它时,我的意思是我已将Direct3D9标头和指针放在全局头文件中的LPDIRECT3DDEVICE9LPDIRECT3D9中,并使用它包围它包括警卫。这适用于我的上一个项目,我比较了两者没有明显的区别。

我已经弄乱了防护标识符,认为它可能已经无效或在其他地方使用并且使用我能想到的最独特的防护标识符给我带来了相同的错误。

我放的时候:

LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3dDevice;
在Main.cpp中

并将其从Headers.h文件中取出,项目编译得很好。但是,我不希望这样,因为我想从每个对象中访问LPDIRECT3DDEVICE9,因为这是我打算设置原始形状的地方。

2 个答案:

答案 0 :(得分:1)

将Headers.h更改为

extern LPDIRECT3D9 d3d;
extern LPDIRECT3DDEVICE9 d3dDevice;

然后把

LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3dDevice;

只有一个.cpp文件(Main.cpp会这样做)

答案 1 :(得分:1)

这是因为您在Headers.h中声明了全局对象。 Globals对象不能多次声明。 (每次包含标题时,都会声明它们......)

你应该改变

LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3dDevice;

通过

extern LPDIRECT3D9 d3d;
extern LPDIRECT3DDEVICE9 d3dDevice;

在你的Headers.h中,并将对象的声明放在Main.cpp中,例如:

// main.cpp
LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3dDevice;