2013-07-08 8 views
0

Я пытаюсь настроить базовое приложение на данный момент, и я хочу использовать Direct3D9 в качестве API для рисования примитивных фигур. Например, я хочу создать круг, который будет нарисован объектом окружности и треугольником в треугольном объекте и т. Д.Ошибки LNK2005 с использованием Direct3D9

Проблема заключается в том, что я получаю ошибки LNK2005, где я не ожидаю их увидеть. Это или я пропустил что-то очень очевидное, потому что я использовал этот метод настройки Direct3D9 до этого без проблем.

Вот фактическое сообщение об ошибке я получаю от компилятора (VS 2010)

1>RigidBody.obj : error LNK2005: "struct IDirect3DDevice9 * d3dDevice" ([email protected]@[email protected]@A) already defined in Main.obj 
1>RigidBody.obj : error LNK2005: "struct IDirect3D9 * d3d" ([email protected]@[email protected]@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 и круг), хотя только 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-файл, но в этих файлах «placeholder» не используется ни один метод (или какой-либо код).

Так может кто-нибудь понять, почему я купил эту ошибку? Я надеюсь, что это будет просто, но я не уверен, так как я создал Direct3D 9 таким образом, чтобы не возникало проблем.

Что я имею в виду, когда я говорю, я поставил его на этом пути до того, что я поставил заголовки Direct3D9 и указатели на LPDIRECT3DDEVICE9 и LPDIRECT3D9 в глобальном файл заголовок и просто окружал его с помощью включает охрану. Это сработало для моего последнего проекта, и я сравнил их без очевидной разницы.

Я испортил идентификаторы охранников, считая, что он был недействительным или использовался в другом месте, и используя самый уникальный идентификатор охранника, который, как я мог подумать, представил мне ту же ошибку.

Когда я кладу:

LPDIRECT3D9 d3d; 
LPDIRECT3DDEVICE9 d3dDevice; 

в main.cpp и вывести его из файла Headers.h, проект компилируется нормально. Тем не менее, я не хочу этого, поскольку я хочу получить доступ к LPDIRECT3DDEVICE9 изнутри каждого объекта, поскольку именно здесь я намерен установить примитивные фигуры.

ответ

1

Это потому, что вы объявляете глобальный объект Headers.h. Объект Globals не может быть объявлен более одного раза. (каждый раз, когда вы включаете заголовок, они будут объявлены ...)

вы должны изменить

LPDIRECT3D9 d3d; 
LPDIRECT3DDEVICE9 d3dDevice; 

по

extern LPDIRECT3D9 d3d; 
extern LPDIRECT3DDEVICE9 d3dDevice; 

в вас Headers.h и поместить объявление объектов в main.cpp, например:

// main.cpp 
LPDIRECT3D9 d3d; 
LPDIRECT3DDEVICE9 d3dDevice; 
+0

Большое спасибо за объяснение и быстрый ответ. Я в недоумении относительно того, как я ушел с НЕ используя ключевое слово extern в моем последнем приложении. – Chris

+0

Добро пожаловать! Не забудьте указать на вопрос, как ответить, если ваша ошибка ушла :-) –

1

Изменение Headers.h в

extern LPDIRECT3D9 d3d; 
extern LPDIRECT3DDEVICE9 d3dDevice; 

И поставил

LPDIRECT3D9 d3d; 
LPDIRECT3DDEVICE9 d3dDevice; 

только в одном .cpp файл (main.cpp будет делать)

+0

Спасибо для быстрого ответа. Решила мою проблему сразу. – Chris