2011-10-26 3 views
1

Je vais avoir un problème très frustrant mise en place d'un cadre 9 DirectX (sans rapport avec la question .. Je pense) dans VS 2010. Voici mon cadre de DirectX:question Linker avec Visual Studio 2010 Pro

#ifndef _DX9_H_ 
#define _DX9_H_ 

// window includes 
#define WIN32_LEAN_AND_MEAN 
#include <Windows.h> 

// required for ush typedef and window properties to setup backbuffer 
#include "sys_params.h" 

// directx9 includes 
#define DIRECTINPUT_VERSION 0x0800 
#include <d3dx9.h> 
#include <dinput.h> 
#include <DxErr.h> 
#include <vector> 
#include <iterator> 

// directx9 libraries 
#pragma comment(lib, "d3d9.lib") 
#pragma comment(lib, "d3dx9.lib") 
#pragma comment(lib, "dinput8.lib") 
#pragma comment(lib, "dxguid.lib") 
#pragma comment(lib, "dxerr.lib") 

namespace nsdx9 
{ 
    using nssysprms::ush; 

    #define CheckHR(hr) CheckForDXError(__FILE__, __LINE__, hr) 

    class DX9 
    { 
     public: 
      DX9(HINSTANCE& inst, int cmdShow, const std::string& title, ush wndwidth, ush wndheight, short wndx, short wndy); 
      ~DX9(); 

      // windows message processor 
      UINT ProcessMessages(); 

      // --- DIRECTX GAME FUNCTIONS --- // 
      // input functions 
      void InputUpdate(); 
      BYTE KeyHeld(ush key); 
      bool KeyPressed(ush key); 

      // sprite functions 
      const LPD3DXSPRITE& GetSpriteInterface(); 
      void SpriteBeginDraw(DWORD flags = D3DXSPRITE_ALPHABLEND); 
      void SpriteEndDraw(); 

      // font functions 
      void MakeFont(int height, int width, UINT weight = FW_DONTCARE, LPCSTR face = "Calibri", bool italic = false); 
      const LPD3DXFONT& GetFontAtIndex(ush index); 
      const std::vector<LPD3DXFONT>& GetFontVector(); 
      // --- END DIRECTX GAME FUNCTIONS --- // 

     private: 
      // --- WINDOW FUNCTIONS/VARIABLES --- // 
      WNDCLASSEX _wc; 
      HWND _hwnd; 
      MSG _msg; 

      HINSTANCE _inst; 
      std::string _title; 

      static LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wprm, LPARAM lprm); 
      // --- END WINDOW FUNCTIONS/VARIABLES --- // 

      // --- DIRECTX FUNCTIONS/VARIABLES --- // 
      // D3D interfaces 
      LPDIRECT3D9 _d3d; 
      LPDIRECT3DDEVICE9 _d3ddev; 
      D3DPRESENT_PARAMETERS _d3dpp; 

      // directinput interfaces 
      LPDIRECTINPUT8 _dInput; 
      LPDIRECTINPUTDEVICE8 _diMouse; 
      LPDIRECTINPUTDEVICE8 _diKeyboard; 

      DIMOUSESTATE _mouseState; 
      BYTE _keys[256]; 
      bool _keyStates[256]; 
      bool _keyboardStateChanged; 

      void AcquireInputDevice(const LPDIRECTINPUTDEVICE8& dev); 

      // sprite interfaces 
      LPD3DXSPRITE _spriteBatch; 

      // font vector 
      std::vector<LPD3DXFONT> _fonts; 

      // hresult checker, for debugging only 
      void CheckForDXError(const char *file, int line, HRESULT hr); 
      // --- END DIRECTX FUNCTIONS/VARIABLES --- // 
    }; 

    /*=================================================*/ 
    /*--------------DIRECTX CONSTRUCTOR----------------*/ 
    /*=================================================*/ 
    DX9::DX9(HINSTANCE& inst, int cmdShow, const std::string& title, ush wndwidth, ush wndheight, short wndx, short wndy) 
    { 
     /*=================================================*/ 
     /*--------------WINDOW INITIALIZATION--------------*/ 
     /*=================================================*/ 
     _title = title; 
     _inst = inst; 

     // init window class struct 
     _wc.cbClsExtra = NULL; 
     _wc.cbSize = sizeof(WNDCLASSEX); 
     _wc.cbWndExtra = NULL; 
     _wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 
     _wc.hCursor = LoadCursor(NULL, IDC_ARROW); 
     _wc.hIcon = NULL; 
     _wc.hIconSm = NULL; 
     _wc.hInstance = inst; 
     _wc.lpfnWndProc = (WNDPROC)WinProc; 
     _wc.lpszClassName = title.c_str(); 
     _wc.lpszMenuName = NULL; 
     _wc.style = CS_HREDRAW | CS_VREDRAW; 
     RegisterClassEx(&_wc); 

     // create handle to the window 
     _hwnd = CreateWindow(title.c_str(), 
          title.c_str(), 
          WS_OVERLAPPEDWINDOW, 
          wndx, 
          wndy, 
          wndwidth, 
          wndheight, 
          NULL, 
          NULL, 
          inst, 
          NULL); 

     // required to make the window show up 
     ShowWindow(_hwnd, cmdShow); 
     UpdateWindow(_hwnd); 
     /*=================================================*/ 
     /*--------------END WINDOW INITIALIZATION----------*/ 
     /*=================================================*/ 
     /*=================================================*/ 
     /*--------------DIRECTX INITIALIZATION-------------*/ 
     /*=================================================*/ 
     // --- INITIALIZE DIRECTX9 VARIABLES --- // 
     SecureZeroMemory(&_d3dpp, sizeof(_d3dpp)); 
     SecureZeroMemory(&_mouseState, sizeof(_mouseState)); 
     SecureZeroMemory(&_keys, sizeof(_keys)); 

     for (int i = 0; i < 256; i++) 
     { 
      _keyStates[i] = true; 
     } 

     _d3d = NULL; 
     _d3ddev = NULL; 
     _dInput = NULL; 
     _diMouse = NULL; 
     _diKeyboard = NULL; 
     _keyboardStateChanged = false; 
     _spriteBatch = NULL; 
     // --- END INITIALIZE DIRECTX9 VARIABLES --- // 

     // --- DIRECTX9 INITIALIZATION --- // 
     _d3d = Direct3DCreate9(D3D_SDK_VERSION); 

     if (!_d3d) 
     { 
      OutputDebugString("Error: Failed to create Direct3D.\n"); 
     } 

     // set d3d present parameters 
     _d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; 
     _d3dpp.BackBufferCount = 1; 
     _d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; 
     _d3dpp.BackBufferHeight = nssysprms::WND_HEIGHT; 
     _d3dpp.BackBufferWidth = nssysprms::WND_WIDTH; 
     _d3dpp.EnableAutoDepthStencil = 1; 
     _d3dpp.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL; 
     //_d3dpp.FullScreen_RefreshRateInHz 
     _d3dpp.hDeviceWindow = _hwnd; 
     //_d3dpp.MultiSampleQuality 
     //_d3dpp.MultiSampleType 
     _d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; 
     _d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; 
     _d3dpp.Windowed = nssysprms::isWindowed; 

     // create d3d device 
     CheckHR(_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, _hwnd, D3DCREATE_MIXED_VERTEXPROCESSING, &_d3dpp, &_d3ddev)); 
     // --- END DIRECTX9 INITIALIZATION --- // 

     // --- INITIALIZE DIRECTINPUT --- // 
     CheckHR(DirectInput8Create(inst, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&_dInput, NULL)); 

     // create mouse and keyboard 
     CheckHR(_dInput->CreateDevice(GUID_SysKeyboard, &_diKeyboard, NULL)); 
     CheckHR(_dInput->CreateDevice(GUID_SysMouse, &_diMouse, NULL)); 

     // initialize keyboard 
     CheckHR(_diKeyboard->SetDataFormat(&c_dfDIKeyboard)); 
     CheckHR(_diKeyboard->SetCooperativeLevel(_hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND)); 
     AcquireInputDevice(_diKeyboard); 

     // initialize mouse 
     CheckHR(_diMouse->SetDataFormat(&c_dfDIMouse)); 
     CheckHR(_diMouse->SetCooperativeLevel(_hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND)); 
     AcquireInputDevice(_diMouse); 

     // create sprite object 
     CheckHR(D3DXCreateSprite(_d3ddev, &_spriteBatch)); 
     // --- END INITIALIZE DIRECTINPUT --- // 
     /*=================================================*/ 
     /*--------------END DIRECTX INITIALIZATION---------*/ 
     /*=================================================*/ 
    } 
    /*=================================================*/ 
    /*--------------END DIRECTX CONSTRUCTOR------------*/ 
    /*=================================================*/ 
    /*=================================================*/ 
    /*--------------DIRECTX DESTRUCTOR-----------------*/ 
    /*=================================================*/ 
    DX9::~DX9() 
    { 
     // set all stack variables to NULL 
     SecureZeroMemory(&_d3dpp, sizeof(_d3dpp)); 
     SecureZeroMemory(&_mouseState, sizeof(_mouseState)); 
     SecureZeroMemory(&_keys, sizeof(_keys)); 
     SecureZeroMemory(&_keyStates, sizeof(_keyStates)); 

     // free all the D3D interfaces from memory 
     if (!_fonts.empty()) 
     { 
      for (std::vector<LPD3DXFONT>::iterator it = _fonts.begin(); it != _fonts.end(); it++) 
      { 
       // SOLVEPROBLEM figure out why this doesn't work 
       //*it->OnLostDevice(); 
      } 

      _fonts.erase(_fonts.begin(), _fonts.end() - 1); 
     } 

     if (_spriteBatch != NULL) 
     { 
      _spriteBatch->Release(); 
      _spriteBatch = NULL; 
     } 

     if (_diKeyboard != NULL) 
     { 
      _diKeyboard->Release(); 
      _diKeyboard = NULL; 
     } 

     if (_diMouse != NULL) 
     { 
      _diMouse->Release(); 
      _diMouse = NULL; 
     } 

     if (_d3ddev != NULL) 
     { 
      _d3ddev->Release(); 
      _d3ddev = NULL; 
     } 

     if (_d3d != NULL) 
     { 
      _d3d->Release(); 
      _d3d = NULL; 
     } 

     // free the window class from memory 
     UnregisterClass(_title.c_str(), _inst); 
    } 
    /*=================================================*/ 
    /*--------------END DIRECTX DESTRUCTOR-------------*/ 
    /*=================================================*/ 
    /*=================================================*/ 
    /*--------------HRESULT ERROR CHECK----------------*/ 
    /*=================================================*/ 
    void DX9::CheckForDXError(const char *file, int line, HRESULT hr) 
    { 
     if (SUCCEEDED(hr)) 
     { 
      return; 
     } 

     // Get the direct X error and description 
     char desc[1024]; 
     sprintf_s(desc,"(DX) %s - %s", DXGetErrorString(hr), DXGetErrorDescription(hr)); 

     // Output the file and line number in the correct format + the above DX error 
     char buf[2048]; 
     sprintf_s(buf,"%s(%d) : Error: %s\n", file, line, desc); 
     OutputDebugString(buf); 
    } 
    /*=================================================*/ 
    /*--------------END HRESULT ERROR CHECK------------*/ 
    /*=================================================*/ 
    /*=================================================*/ 
    /*--------------MESSAGE PROCESSOR------------------*/ 
    /*=================================================*/ 
    UINT DX9::ProcessMessages() 
    { 
     if (PeekMessage(&_msg, NULL, NULL, NULL, PM_REMOVE)) 
     { 
      TranslateMessage(&_msg); 
      DispatchMessage(&_msg); 
     } 

     return _msg.message; 
    } 
    /*=================================================*/ 
    /*--------------END MESSAGE PROCESSOR--------------*/ 
    /*=================================================*/ 
    /*=================================================*/ 
    /*--------------MESSAGE HANDLER--------------------*/ 
    /*=================================================*/ 
    LRESULT CALLBACK DX9::WinProc(HWND hwnd, UINT msg, WPARAM wprm, LPARAM lprm) 
    { 
     switch (msg) 
     { 
      case WM_DESTROY: 
       PostQuitMessage(0); 
       break; 
     } 

     return DefWindowProc(hwnd, msg, wprm, lprm); 
    } 
    /*=================================================*/ 
    /*--------------END MESSAGE HANDLER----------------*/ 
    /*=================================================*/ 
    /*=================================================*/ 
    /*--------------DIRECTINPUT FUNCTIONS--------------*/ 
    /*=================================================*/ 
    // for init only, helper function to initially acquire the 
    // mouse and keyboard 
    void DX9::AcquireInputDevice(const LPDIRECTINPUTDEVICE8& dev) 
    { 
     // loop and attempt to acquire the device until success 
     while (FAILED(dev->Acquire())) 
     { 
      dev->Acquire(); 
     } 
    } 

    // update the state of the mouse and keyboard 
    void DX9::InputUpdate() 
    { 
     _diKeyboard->GetDeviceState(sizeof(_keys), (LPVOID)_keys); 
     _diMouse->GetDeviceState(sizeof(_mouseState), (LPVOID)&_mouseState); 

     // after directinput has been updated, check to see if any keys are no, 
     // longer pressed, and reset the keystate array at that key's index if, 
     // this is the case 
     // keystates true = key is available for key press 
     if (_keyboardStateChanged) 
     { 
      for (int i = 0; i < 256; i++) 
      { 
       if (!KeyHeld(i)) 
       { 
        _keyStates[i] = true; 
       } 
      } 
     } 

     _keyboardStateChanged = false; 
    } 

    // captures a key being held down 
    BYTE DX9::KeyHeld(ush key) 
    { 
     return _keys[key] & 0x80; 
    } 

    // captures a single key press 
    bool DX9::KeyPressed(ush key) 
    { 
     if (KeyHeld(key) && _keyStates[key]) 
     { 
      _keyStates[key] = false; 
      return true; 
     } 
     else 
     { 
      if (!KeyHeld(key) && !_keyStates[key]) 
      { 
       _keyboardStateChanged = true; 
      } 

      return false; 
     } 
    } 
    /*=================================================*/ 
    /*--------------END DIRECTINPUT FUNCTIONS----------*/ 
    /*=================================================*/ 
    /*=================================================*/ 
    /*--------------SPRITE FUNCTIONS-------------------*/ 
    /*=================================================*/ 
    // returns the sprite interface 
    const LPD3DXSPRITE& DX9::GetSpriteInterface() 
    { 
     return _spriteBatch; 
    } 

    // begin drawing with the sprite batch 
    void DX9::SpriteBeginDraw(DWORD flags) 
    { 
     _spriteBatch->Begin(flags); 
    } 

    // end sprite batch drawing 
    void DX9::SpriteEndDraw() 
    { 
     _spriteBatch->End(); 
    } 
    /*=================================================*/ 
    /*--------------END SPRITE FUNCTIONS---------------*/ 
    /*=================================================*/ 
    /*=================================================*/ 
    /*--------------FONT FUNCTIONS---------------------*/ 
    /*=================================================*/ 
    // create a font 
    void DX9::MakeFont(int height, int width, UINT weight, LPCSTR face, bool italic) 
    { 
     LPD3DXFONT newfont; 

     CheckHR(D3DXCreateFont(_d3ddev, 
           height, 
           width, 
           weight, 
           0, 
           italic, 
           DEFAULT_CHARSET, 
           OUT_DEFAULT_PRECIS, 
           CLEARTYPE_QUALITY, 
           DEFAULT_PITCH | FF_DONTCARE, 
           face, 
           &newfont)); 

     _fonts.push_back(newfont); 
    } 

    // gets a font at the specified index 
    const LPD3DXFONT& DX9::GetFontAtIndex(ush index) 
    { 
     return _fonts[index]; 
    } 

    const std::vector<LPD3DXFONT>& DX9::GetFontVector() 
    { 
     return _fonts; 
    } 
    /*=================================================*/ 
    /*--------------END FONT FUNCTIONS-----------------*/ 
    /*=================================================*/ 
} 
#endif 

Cela ne fait vraiment rien mais créer et initialiser une fenêtre, DirectX et quelques fonctions de base DirectX.

L'erreur réelle est la suivante:

Error 1 error LNK2005: "public: __thiscall nsdx9::DX9::DX9(struct HINSTANCE__ * &,int,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,unsigned short,unsigned short,short,short)" ([email protected]@@[email protected][email protected]@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]) already defined in game_manager.obj C:\Users\JAREK\documents\visual studio 2010\Projects\example\example\main.obj 

Cette erreur est répétée pour chaque fonction dans dx9.h. Si j'inclue UNIQUEMENT dx9.h dans main.cpp, je ne reçois pas cette erreur. C'est seulement si j'inclue dx9.h dans n'importe quel autre fichier cpp, ou si j'utilise l'un des paramètres de dx9.h dans les fichiers cpp qui ont accès à dx9.h en étant inclus après dx9.h dans main.cpp Erreur. Cela semble confus, alors voici quelques échantillons provenant d'autres parties du programme:

main.cpp:

#include "sys_params.h" 
#include "dx9.h" 
#include "game_manager.h" 

int WINAPI WinMain (HINSTANCE inst, HINSTANCE pinst, LPSTR cmdLine, int cmdShow) 
{ 
    // state of the program 
    bool appEnd = false; 

    // create and initialize the window and directx9 
    nsdx9::DX9* _dx9 = new nsdx9::DX9(inst, cmdShow, nssysprms::GAME_TITLE, 
             nssysprms::WND_WIDTH, nssysprms::WND_HEIGHT, 
             nssysprms::WND_POS_X, nssysprms::WND_POS_Y); 

    // create and initialize the game manager 
    Game_Manager* _mngr = new Game_Manager(_dx9); 

    // Windows message handler 
    // also the entry point for the main game loop 
    while (_dx9->ProcessMessages() != WM_QUIT && !appEnd) 
    { 
     if (!_mngr->Game_Run()) 
     { 
      appEnd = true; 
     } 
    } 

    // clean up everything 
    delete _mngr; 
    delete _dx9; 

    return 0; 
} 

game_manager.h:

#ifndef _GAME_MANAGER_H_ 
#define _GAME_MANAGER_H_ 

#include <stack> 
#include <vector> 
#include "dx9.h" 
#include "screen.h" 
#include "message_handler.h" 

class Game_Manager 
{ 
    public: 
     Game_Manager(nsdx9::DX9* dx9); 
     ~Game_Manager(); 
     bool Game_Run(); 

    private: 
     nsdx9::DX9* _dx9; 
     std::stack<Screen*> _screens; 
     Message_Handler* _msg_hnd; 

     // *** DECLARE SCREENS HERE *** // 

     void InitFonts(); 
     void InitScreens(); 
}; 
#endif 

Cela devrait être ce qui est réellement la cause de la problème. Le problème provient de main.cpp via game_manager.h. Rien que j'ai essayé a résolu le problème pour moi. J'ai inclus des gardes d'en-tête dans dx9.h, donc je n'ai aucune idée de ce qui pourrait causer cela. Si vous avez besoin de plus d'informations, s'il vous plaît faites le moi savoir. Merci!

Répondre

0

N'incluez pas l'implémentation dans le fichier d'en-tête. Cela entraîne la compilation de l'implémentation partout où elle est incluse.

par exemple:

/*=================================================*/ 
/*--------------DIRECTX CONSTRUCTOR----------------*/ 
/*=================================================*/ 
DX9::DX9(HINSTANCE& inst, int cmdShow, const std::string& title, ush wndwidth, ush wndheight, short wndx, short wndy) 
    { 
    .... et al 

mettre que dans sa propre cpp

+0

Merci beaucoup! Je n'ai jamais connu cette règle. – Eternalspirit

1

Vos définitions des méthodes DX9 (par opposition à simplement la définition de classe) semblent être dans le fichier d'en-tête dx9.h - donc vous enfreindre la règle de définition unique de C++ lorsque vous incluez dx9.h dans plusieurs fichiers .cpp. Pour résoudre ce problème, déplacez les implémentations de méthode dans un fichier .cpp (par exemple dx9.cpp).

+0

Merci beaucoup! Je n'ai jamais connu cette règle. – Eternalspirit