2015-06-09 5 views
0

Вот код и вывод. win_main.cppвизуальная студия не может разрешать статические функции

#include <Windows.h> 
#include <tchar.h> 

#include "d3d9_object.h" 

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

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 
WNDCLASSEX createWndClassEx(HINSTANCE); 
HWND createWindow(const wchar_t *caption, HINSTANCE); 
void exitWithFailure(const wchar_t *message, HINSTANCE); 

const wchar_t gszWndClassName[] = L"MainWindowClassName"; 
WNDCLASSEX gWndClassEx; 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, int iCmdShow) 
{ 
    HWND hwnd = NULL; 
    MSG msg = { 0 }; 
    BOOL bReturn; 

    WNDCLASSEX wndClassEx = createWndClassEx(hInstance); 
    if (!RegisterClassEx(&wndClassEx)) exitWithFailure(L"Cannot create window class", hInstance); 

    hwnd = createWindow(L"£d \u018Fditor", hInstance); 
    if (!hwnd) 
     exitWithFailure(L"Cannot create window", hInstance); 
    if (gpd39o->init(hwnd) == false) 
     exitWithFailure(L"Cannot initilize Direct3D", hInstance); 
    ShowWindow(hwnd, SW_MAXIMIZE); 
    UpdateWindow(hwnd); 
    if (!gpd39o->clear()) MessageBox(hwnd, L"Cannot clear device to color", L"Error!", MB_OK | MB_ICONERROR); 
    while ((bReturn = GetMessage(&msg, hwnd, 0, 0))) { 
     if (bReturn == -1) { 
      exitWithFailure(L"Message loop error", hInstance); 
     } 
     else { 
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
     } 
    } 

    gpd39o->deinit(); 
    UnregisterClass(gszWndClassName, hInstance); 
    return EXIT_SUCCESS; 
} 

void exitWithFailure(const wchar_t *message, HINSTANCE h) 
{ 
    MessageBox(NULL, message, L"Error!", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL); 
    gpd39o->deinit(); 
    UnregisterClass(gszWndClassName, h); 
    exit(EXIT_FAILURE); 
} 

LRESULT CALLBACK WndProc(HWND h, UINT m, WPARAM w, LPARAM l) 
{ 
    if (m == WM_DESTROY) { 
     PostQuitMessage(0); 
     return 0; 
    } 

    return DefWindowProc(h, m, w, l); 
} 

HWND createWindow(const wchar_t *c, HINSTANCE h) 
{ 
    DWORD winStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME; 
    return CreateWindowEx(WS_EX_APPWINDOW, gszWndClassName, c, winStyle, 
     CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
     NULL, NULL, h, NULL); 
} 

WNDCLASSEX createWndClassEx(HINSTANCE h) 
{ 
    WNDCLASSEX w = { 0 }; 
    w.cbSize = sizeof(WNDCLASSEX); 
    w.hInstance = h; 
    w.style = CS_HREDRAW | CS_VREDRAW; 
    w.lpszClassName = (LPCWSTR)gszWndClassName; 
    w.lpfnWndProc = WndProc; 
    return w; 
} 

класс со всеми статическими членами, который вызывает проблемы.

#ifndef _D3D9_OBJECT_H_ 
#define _D3D9_OBJECT_H_ 

#include <d3d9.h> 
#include <d3dx9.h> 
#include <d3dx9math.h> 
#include "vertex_types.h" 

/* 
- sm_ - static member 
- d39 - Direct3D9 
- f - float 
*/ 
class D3D9Object 
{ 
public: 
    D3D9Object() { } 

    static bool init(HWND); 
    static void deinit(); 
    static bool clear(int color = D3DCOLOR_XRGB(0, 0, 0), float fZDepth = 1.0f); 

    static IDirect3D9 * sm_pId39; 
    static IDirect3DDevice9 * sm_pd39Device; 

    ~D3D9Object() { } 
private: 
    static HWND sm_hWnd; 
    static float sm_fAspectRatio; 
    static HRESULT sm_hResult; 

    static bool createDevice(); 
    static void setPresentParams(D3DPRESENT_PARAMETERS &); 
    static bool setDefaultRenderState(); 
}; 

extern D3D9Object * gpd39o; 

#endif 

d3d9_object.cpp #include "d3d9_object.h"

IDirect3D9 * D3D9Object::sm_pId39; 
IDirect3DDevice9 * D3D9Object::sm_pd39Device; 
HRESULT D3D9Object::sm_hResult; 
HWND D3D9Object::sm_hWnd; 
float D3D9Object::sm_fAspectRatio; 

bool D3D9Object::init(HWND h) 
{ 
    if (!h) return false; 
    sm_hWnd = h; 
    if (!(sm_pId39 = Direct3DCreate9(D3D_SDK_VERSION))) return false; 
    if (!createDevice()) return false; 
    if (!setDefaultRenderState()) return false; 
    return true; 
} 

void D3D9Object::deinit() 
{ 
    if (sm_pId39) sm_pId39->Release(); 
    if (sm_pd39Device) sm_pd39Device->Release(); 
    sm_pId39 = NULL; 
    sm_pd39Device = NULL; 
    sm_hWnd = NULL; 
} 

bool D3D9Object::clear(int c, float z) 
{ 
    sm_hResult = sm_pd39Device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, c, z, 0); 
    return sm_hResult == D3D_OK; 
} 

bool D3D9Object::setDefaultRenderState() 
{ 
    sm_hResult = sm_pd39Device->SetRenderState(D3DRS_LIGHTING, FALSE); 
    if (sm_hResult != D3D_OK) return false; 
    sm_hResult = sm_pd39Device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); 
    if (sm_hResult != D3D_OK) return false; 
    return true; 
} 

bool D3D9Object::createDevice() 
{ 
    if (sm_pd39Device || !sm_pId39) return false; 
    D3DPRESENT_PARAMETERS params = { 0 }; 
    setPresentParams(params); 
    sm_fAspectRatio = (float)params.BackBufferWidth/(float)params.BackBufferHeight; 
    sm_hResult = sm_pId39->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, sm_hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, 
     &params, &sm_pd39Device); 
    if (sm_hResult != D3D_OK) { 
     sm_hResult = sm_pId39->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, sm_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, 
      &params, &sm_pd39Device); 
     if (sm_hResult != D3D_OK) return false; 
    } 
    return true; 
} 

void D3D9Object::setPresentParams(D3DPRESENT_PARAMETERS &p) 
{ 
    ZeroMemory(&p, sizeof(D3DPRESENT_PARAMETERS)); 
    p.hDeviceWindow = sm_hWnd; 
    p.BackBufferCount = 1; 
    p.SwapEffect = D3DSWAPEFFECT_FLIP; 
    p.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; 
    p.EnableAutoDepthStencil = TRUE; 
    p.AutoDepthStencilFormat = D3DFMT_D16; 
    RECT r = { 0 }; 
    GetClientRect(sm_hWnd, &r); 
    p.Windowed = true; 
    p.BackBufferWidth = r.right; 
    p.BackBufferHeight = r.bottom; 
    p.BackBufferFormat = D3DFMT_UNKNOWN; 
} 

D3D9Object gd39Object; 
extern D3D9Object * gpd39o = &gd39Object; 

А вот это выход

1>------ Build started: Project: 3DEditor, Configuration: Debug Win32 ------ 
1> win_main.cpp 
1> d3d9_object.h 
1> d3d9_object.cpp 
1> Generating Code... 
1>Debug\d3d9_object.obj : warning LNK4042: object specified more than once; extras ignored 
1>win_main.obj : error LNK2019: unresolved external symbol "public: static bool __cdecl D3D9Object::init(struct HWND__ *)" ([email protected]@@[email protected]@@Z) referenced in function [email protected] 
1>win_main.obj : error LNK2019: unresolved external symbol "public: static void __cdecl D3D9Object::deinit(void)" ([email protected]@@SAXXZ) referenced in function "void __cdecl exitWithFailure(wchar_t const *,struct HINSTANCE__ *)" ([email protected]@[email protected]@@Z) 
1>win_main.obj : error LNK2019: unresolved external symbol "public: static bool __cdecl D3D9Object::clear(int,float)" ([email protected]@@[email protected]) referenced in function [email protected] 
1>C:\Users\User\documents\visual studio 2013\Projects\3DEditor\Debug\3DEditor.exe : fatal error LNK1120: 3 unresolved externals 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 

Не могли бы вы сказать мне, что может привести к LNK4042? Я не получаю, где объект указан несколько раз. И я попробовал google LNK2019, но все темы, которые я нашел, были синтаксическими. Я проверил все, что мог найти, но код кажется хорошим (я был бы рад, если бы это было не так, и вы просто указали мне свою ошибку). Иногда, когда я делаю небольшие изменения в коде, линкера удается, но после нескольких компиляций он снова не работает. Кроме того, до того, как я добавил «ясную» функцию, она работала, я добавил эту небольшую функцию, и она работала только один раз с тех пор (до того, как я добавил эту функцию, иногда компоновщик не сработал, но теперь он иногда преуспевает). Я знаю, что есть другие способы реализации singleton, но у меня есть код, подобный этому, и он отлично работает. Спасибо

ответ

0

Ваш вывод сборки показывает, что вам как-то удалось заставить компилятор фактически компилироватьd3d9_object.h файл. Это совершенно неприемлемо. Вы не должны компилировать файлы заголовков. Предполагается, что файлы заголовков будут включены в файлы .cpp, а не скомпилированы сами.

Из-за этой проблемы, ваш d3d9_object.h, после того, как сила, подаваемыми компилятор производит d3d9_object.obj файл, который затирает (перезаписывает) надлежащего d3d9_object.obj файл, полученный из d3d9_object.cpp. Это приводит к LNK4042 и дальнейшим ошибкам компоновщика.

Не пытайтесь компилировать d3d9_object.h. Узнайте, как это удалось скомпилировать и устранить проблему.

+0

Я сделал ошибку, когда создавал файл. Сначала я создаю .cpp, а затем переименовал его в .h. Я думал, что визуальная студия думает о файле в соответствии с его расширением. благодаря – sasha199568

Смежные вопросы