Expected "}" at end of input when including d3dx11.h - c++

I know what the error "Expected '}' before end of input" means, the issue I'm having is that the error appears to be in one of the files included with d3dx11.h, as when I don't include this file and comment out the DirectX calls in my code I don't get the error.
When I search for this error, I get results, but all results I find are errors in the users code (additional or missing braces), the error for me seems to be occurring inside the included files so after 6 hours I haven't found any help.
I'm relatively new to C++, and at this time I'm just trying to experiment and understand how things work, so I don't really care too much about naming conventions or what I may be putting in the header files that should go into the corresponding cpp file according to standard practice. My code may not be the cleanest and may have some inefficiencies, feel free to additionally point out places I could improve upon, but for this question I'm mostly asking what's causing the error:
C:/Program Files/CodeLite/.../main.cpp:33:1: error: expected '}' at end of input
As I said earlier, this error doesn't occur until I include DirectX.
main.cpp
#ifndef INCL_WINDOWS_H
#include <windows.h>
#include <windowsx.h>
#define INCL_WINDOWS_H
#endif
#include <iostream>
#ifdef _MSC_VER
# pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif
#define OS_WINDOWS
#include "WindowUtils.h"
#include "RenderUtils_Creation.h"
using namespace std;
int main()
{
Window window("Test Window",100,100,900,900);
while(window.getAlive())
{
window.process();
}
return window.getExitCode();
} // <-- Line 33, error occurs here, only when DX is included in RenderUtils_Creation.h
WindowUtils.h
#ifndef INCL_WINDOW_UTILS
#define INCL_WINDOW_UTILS
enum DisplayMode // Currently Unused (TBI)
{
WINDOWED,
FULLSCREEN,
WINDOWED_NOBORDER
};
// DEFINE TEMPLATE FOR IMPLEMENTATION FEATURES
class ImplementationFeatures;
// DEFINE PLATFORM SPECIFIC IMPLEMENTATION OF IMPLEMENTATION FEATURES
#ifdef OS_WINDOWS
class ImplementationFeatures
{
public:
static LRESULT CALLBACK WinProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
HINSTANCE procInst;
WNDCLASSEX wndStruct;
HWND windowHandle;
MSG msg;
};
#endif
// DEFINE TEMPLATE FOR WINDOW
class Window
{
public:
ImplementationFeatures features;
Window(char*, int, int, int, int);
bool getAlive();
void setDisplayMode(DisplayMode);
void process();
void update();
int getExitCode();
};
// DEFINE PLATFORM-SPECIFIC IMPLEMENTATIONS OF WINDOW
#ifdef OS_WINDOWS
Window::Window(char* title, int xPos, int yPos, int width, int height)
{
ImplementationFeatures feature;
LPCTSTR strTitle = title;
feature.procInst = GetModuleHandle(NULL);
feature.wndStruct.cbSize = sizeof(WNDCLASSEX);
feature.wndStruct.style = CS_HREDRAW | CS_VREDRAW;
feature.wndStruct.lpfnWndProc = feature.WinProc;
feature.wndStruct.cbClsExtra = 0;
feature.wndStruct.cbWndExtra = 0;
feature.wndStruct.hInstance = GetModuleHandle(NULL);
feature.wndStruct.hIcon = NULL;
feature.wndStruct.hCursor = NULL;
feature.wndStruct.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
feature.wndStruct.lpszMenuName = NULL;
feature.wndStruct.lpszClassName = "WindowClassName";
feature.wndStruct.hIconSm = LoadIcon(NULL,IDI_APPLICATION);
RegisterClassEx(&(feature.wndStruct));
feature.windowHandle = CreateWindowEx(WS_EX_CONTROLPARENT, "WindowClassName", strTitle, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE, xPos, yPos, width, height, NULL, NULL, GetModuleHandle(NULL), NULL);
ShowWindow(feature.windowHandle, 1);
UpdateWindow(feature.windowHandle);
features = feature;
}
bool Window::getAlive()
{
return GetMessage(&features.msg, NULL, 0, 0) > 0;
}
void Window::process()
{
TranslateMessage(&(features.msg));
DispatchMessage(&(features.msg));
}
void Window::update()
{
UpdateWindow(features.windowHandle);
}
void Window::setDisplayMode(DisplayMode mode)
{
switch(mode)
{
case WINDOWED:
ShowWindow(features.windowHandle,1);
break;
case WINDOWED_NOBORDER:
ShowWindow(features.windowHandle,1);
break;
case FULLSCREEN:
ShowWindow(features.windowHandle,1);
break;
}
}
int Window::getExitCode()
{
return features.msg.wParam;
}
#endif // End OS_WINDOWS
#endif // End INCL_WINDOW_UTILS
RenderUtils_Creation.h
#ifndef INCL_RENDER_UTILS_CRTN
#define INCL_RENDER_UTILS_CRTN
//This won't be included on the main.cpp because of the header guard
//Bug is included in case of use on other files
#include "WindowUtils.h"
#ifdef OS_WINDOWS
// Use Direct3D
//#define SKIP_DIRX // To quickly go back and forth testing if error is DX related
// When commented out d3d11.h and d3dx11.h are included with their libs
// When not commented none are included
// The error only occurs when this is commented.
#ifndef SKIP_DIRX
// Import Headers
#include <d3d11.h>
#include <d3dx11.h>
// include the Direct3D Library files
#pragma comment (lib, "d3d11.lib")
#pragma comment (lib, "d3dx11.lib")
#endif
#endif // End of OS_WINDOWS
#endif // End of INCL_RENDER_UTILS_CRTN
main.cpp is the only .cpp file and has no header. I'm attempting to create a cross-platform library for interfacing with different OS and graphics APIs. By defining OS_WINDOWS DirectX will be the API compiled against, for Mac I would then add code to interface to Metal, etc. I'm use to this abstraction, I've done similar with Java in the past, but this error is confusing me.
Edit - Additional info that may be important:
Compiler: MinGW GCC Compiler (TDM-GCC-32)
IDE: CodeLite
Version: 8.2.0
Does library search paths include DirectX SDK 'Lib' folder: Yes
Does include search paths include DirectX SDK 'includes' folder: Yes
Microsoft DirectX SDK (June 2010)
Standard installation
From further research it would appear that at least part of my problem could be because of Microsoft developing their own standards for their C++ compiler. The VisualC++ compiler adds in custom operators, intrinsic functions, macros and alternate versions of other standard functions that don't exist in other compilers because they are not C++ standards, they are custom Microsoft-specific additions. The DirectX header files apparently are reliant on the presence of these features and thus Microsoft essentially is forcing anyone who uses DirectX to use their compiler, at least for certain parts of their program.

Related

Shared global variable with DLL not working

I'm trying to get some code that works on the Mac to work on Windows. The code involves sharing data between a DLL, a static library and the main program. I suspect the problem arises because of the differences in the way that Unix and Windows handle global variables (see, for example, the answers here). However, I haven't figured out how to fix it. Here's a minimal example:
My Visual Studio 2019 solution contains three projects.
Project 1 makes the static library MarinaLib.lib
Header is MarinaLib.h
#pragma once
#include "Marina.h"
Class header is Marina.h
#pragma once
class Marina
{
public:
static Marina* get_marina();
protected:
static Marina* marina_instance;
};
Source file is Marina.cpp
#include "Marina.h"
Marina* Marina::marina_instance { nullptr };
Marina* Marina::get_marina()
{
if( !marina_instance )
marina_instance = new Marina();
return marina_instance;
}
Project 2 makes the DLL MarinaDLL.dll . It #defines MARINADLL_EXPORTS
First source file dllmain.cpp
// dllmain.cpp : Defines the entry point for the DLL application.
#include "framework.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Header file MarinaDLL.h is
#pragma once
#ifdef MARINADLL_EXPORTS
#define QUERY_DECLSPEC __declspec(dllexport)
#else
#define QUERY_DECLSPEC __declspec(dllimport)
#endif
QUERY_DECLSPEC void query_marina();
Second source file is marinaDLL.cpp
#include "MarinaDLL.h"
#include "..\MarinaLib\Marina.h"
void query_marina()
{
auto inst = Marina::get_marina();
}
Project 3 makes the executable MarinaExample.exe and does not #define MARINADLL_EXPORTS. It links in MarinaLib.lib and MarinaDLL.lib
The source file MarinaExample.cpp is
#include "MarinaLib.h"
#include "MarinaDLL.h"
int main()
{
auto instance = Marina::get_marina();
query_marina();
}
In the first line of main(), the code enters Marina::get_marina(). marina_instance is nullptr so the code creates a new Marina and makes marina_instance point to it. This is fine.
In the second line of main(), the code enters query_marina() and from there goes into Marina::get_marina(). At this point marina_instance is nullptr which is not what I want. I would like it to maintain its previous non-null value.
I've seen some examples of solutions to problems in similar code but they don't seem to work in my situation. Any suggestions on how to fix this?
Thanks.
add export modifier to class definition and export the whole class.
In dll and lib build define QUERY_DECLSPEC=export , in exe build as import :
class QUERY_DECLSPEC Marina
{
public:
static Marina* get_marina();
protected:
static Marina* marina_instance;
};

Issue debugging an MFC applicaiton, building but not running

I build the code successfully but it does not debug and comes up with this warning in a wizard miscellaneous code.
"Warning: Destroying non-NULL m_pMainWnd\n"
and
"Warning: Temp map lock count non-zero (%ld).\n",
The aim of this is to create a dialog box that allows a user to input car specifications and a track so a lap time can be calculated.
Source File of Main Dialogue box:
#define _WIN32_WINNT 0x0601
// LapTimeSim.cpp : implementation file
//
#include <iostream>
#include "stdafx.h"
#include "LapTimeSim.h"
#include "afxdialogex.h"
#include "SecondDlg.h"
#include "resource.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
using namespace std;
// LapTimeSim dialog
IMPLEMENT_DYNAMIC(LapTimeSim, CDialogEx);
LapTimeSim::LapTimeSim(CWnd* pParent /*=NULL*/)
: CDialogEx(IDD_DIALOG1, pParent)
{
}
LapTimeSim::~LapTimeSim()
{
}
void LapTimeSim::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(LapTimeSim, CDialogEx)
ON_BN_CLICKED(IDC_CAR, &LapTimeSim::OnBnClickedCar)
ON_BN_CLICKED(IDGO, &LapTimeSim::OnBnClickedGo)
ON_BN_CLICKED(IDC_TRACK, &LapTimeSim::OnBnClickedTrack)
END_MESSAGE_MAP()
// LapTimeSim message handlers
void LapTimeSim::OnBnClickedCar()
{
// TODO: Add your control notification handler code here
CSecondDlg Dlg;
Dlg.DoModal();
}
void LapTimeSim::OnBnClickedGo()
{
// TODO: Add your control notification handler code here
}
void LapTimeSim::OnBnClickedTrack()
{
// TODO: Add your control notification handler code here
}
A Large Header; Header file of main dialog box
==============
#pragma once
// LapTimeSim dialog
class LapTimeSim : public CDialogEx
{
DECLARE_DYNAMIC(LapTimeSim)
public:
LapTimeSim(CWnd* pParent = NULL); // standard constructor
virtual ~LapTimeSim();
// Dialog Data
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DIALOG1 };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedCar();
afx_msg void OnBnClickedGo();
afx_msg void OnBnClickedTrack();
};
Source File of Main Dialogue box:
// SecondDlg.cpp : implementation file
//
#define _WIN32_WINNT 0x0601
#include <iostream>
#include "stdafx.h"
#include "LapTimeSim.h"
#include "afxdialogex.h"
#include "SecondDlg.h"
#include "resource.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CSecondDlg dialog
IMPLEMENT_DYNAMIC(CSecondDlg, CDialog)
CSecondDlg::CSecondDlg(CWnd* pParent /*=NULL*/)
: CDialog(IDD_DIALOG2, pParent)
{
}
CSecondDlg::~CSecondDlg()
{
}
void CSecondDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CSecondDlg, CDialog)
END_MESSAGE_MAP()
// CSecondDlg message handlers
A Large Header; Header file of second dialog box
==============
#pragma once
// CSecondDlg dialog
class CSecondDlg : public CDialog
{
DECLARE_DYNAMIC(CSecondDlg)
public:
CSecondDlg(CWnd* pParent = NULL); // standard constructor
virtual ~CSecondDlg();
// Dialog Data
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DIALOG2 };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
};
Source File : appmodule.cpp writeen by the wizard
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#include "sal.h"
/////////////////////////////////////////////////////////////////////////////
// export WinMain to force linkage to this module
extern int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine, int nCmdShow);
extern "C" int WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine, int nCmdShow)
#pragma warning(suppress: 4985)
{
// call shared/exported WinMain
return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
/////////////////////////////////////////////////////////////////////////////
// initialize app state such that it points to this module's core state
BOOL AFXAPI AfxInitialize(BOOL bDLL, DWORD dwVersion)
{
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
pModuleState->m_bDLL = (BYTE)bDLL;
ASSERT(dwVersion <= _MFC_VER);
UNUSED(dwVersion); // not used in release build
#ifdef _AFXDLL
pModuleState->m_dwVersion = dwVersion;
#endif
#ifdef _MBCS
// set correct multi-byte code-page for Win32 apps
if (!bDLL)
_setmbcp(_MB_CP_ANSI);
#endif //_MBCS
return TRUE;
}
// force initialization early
#pragma warning(disable: 4074)
#pragma init_seg(lib)
#ifndef _AFXDLL
void AFX_CDECL _AfxTermAppState()
{
// terminate local data and critical sections
AfxTermLocalData(NULL, TRUE);
AfxCriticalTerm();
// release the reference to thread local storage data
AfxTlsRelease();
}
#endif
#ifndef _AFXDLL
char _afxInitAppState = (char)(AfxInitialize(FALSE, _MFC_VER), atexit(&_AfxTermAppState));
#else
char _afxInitAppState = (char)(AfxInitialize(FALSE, _MFC_VER));
#endif
/////////////////////////////////////////////////////////////////////////////
Source File - Wizard code coming up with warning:
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#include "sal.h"
/////////////////////////////////////////////////////////////////////////////
// Standard WinMain implementation
// Can be replaced as long as 'AfxWinInit' is called first
int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine, int nCmdShow)
{
ASSERT(hPrevInstance == NULL);
int nReturnCode = -1;
CWinThread* pThread = AfxGetThread();
CWinApp* pApp = AfxGetApp();
// AFX internal initialization
if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))
goto InitFailure;
// App global initializations (rare)
if (pApp != NULL && !pApp->InitApplication())
goto InitFailure;
// Perform specific initializations
if (!pThread->InitInstance())
{
if (pThread->m_pMainWnd != NULL)
{
TRACE(traceAppMsg, 0, "Warning: Destroying non-NULL m_pMainWnd\n");
pThread->m_pMainWnd->DestroyWindow();
}
nReturnCode = pThread->ExitInstance();
goto InitFailure;
}
nReturnCode = pThread->Run();
InitFailure:
#ifdef _DEBUG
// Check for missing AfxLockTempMap calls
if (AfxGetModuleThreadState()->m_nTempMapLock != 0)
{
TRACE(traceAppMsg, 0, "Warning: Temp map lock count non-zero (%ld).\n",
AfxGetModuleThreadState()->m_nTempMapLock);
}
AfxLockTempMaps();
AfxUnlockTempMaps(-1);
#endif
AfxWinTerm();
return nReturnCode;
}
/////////////////////////////////////////////////////////////////////////////
(See my answer to this SO: Cannot create main window?, it looks very similar to your issue)
If you have created this project with wizard then you should also have source files for CWinApp implementation. If its some other kind of wizard generated application then you still should somewhere have an InitInstance like method. with following lines of code:
LapTimeSim dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
(I assume here that LapTimeSim is your main entry dialog). If you remove above lines, you will get the exact same trace and behaviour as in your description (I checked this locally).
So you should check if you have by mistake removed them, or recreate project from MFC template wizard.

C++ Classes: Conceptual Class Doppelganger: LNK2005

Sheesh. I've run into the infamous LNK2005 error when defining my class and I can't seem to place the issue.
(I'm tearing apart an equally infamous singleton of mine to reflect well, organization.) The initial said singleton was coded... ...in such a divergent, brilliant way... as to avoid all of the C++ OPP principles and concepts I was ignorant to at the time, but it worked! ....Somehow. Though some fluke of the simplest C++ concepts it did. Now I need organization, compilation speed, and advanced structuring techniques to make it work fast, and- you get it.
A-Anyway. After splitting it up, and having to rewrite some, I've noticed a necessity. I must declare multiple .cpp files simply because the compiler is irked massively by double declarations, and the usual header class definitions.
Additionally I've used preprocessor directives accordingly as applicable. But something still remains wrong.
Note(Edit): I've rewritten the question to provide error given.
Consider:
D3D.h
#include "Infinity.h"
class Direct3D :
public Infinity
{
public:
Direct3D();
~Direct3D();
IDXGISwapChain *Swapchain; //Display modes.
static ID3D11Device *Device;
static ID3D11DeviceContext *DeviceContext;
static ID3D11RenderTargetView *RenderTargetView;
void D3D_Start(float width, float height);
void D3D_Render();
void D3D_Terminate();
void ViewPort(float Height, float Width, float MaxDepth, float MinDepth, float TopLeftX, float TopLeftY);
}Direct3D;
...and Windows.h
#include "Infinity.h"
class Windows :
public Infinity
{
public:
Windows();
~Windows();
bool DisplayWindow(int width, int height, HINSTANCE hInstance);
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
}Windows;
Finally, Infinity.h
#pragma once
class Infinity{
public:
Infinity();
~Infinity();
static HWND hWnd;
};
Whereas all implementations are in their respective .cpp files. Besides #pragma, I've used #ifndef ... #endif. I suspect that I may be inadvertently calling a kind of implementation by auto-initializing the classes in their header files. But it looks insanely kosher, and allows me to declare function members as:
Direct3D.D3D_Start() without stating a static member, Direct3D::D3D_Start().
Should my headers all be static?
Edit: Below, the .cpp file:
#include "stdafx.h"
#include "Infinity.h"
#include "Windows.h"
#include "Direct3D.h"
MSG msg;
float width = 1024;
float height = 768;
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
windows.DisplayWindow(1280, 900, hInstance);
direct3D.D3D_Start(width, height);
direct3D.ViewPort(height, width, 1.0f, 0.0f, 0, 0);
while (WM_QUIT != msg.message){
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else{
direct3D.D3D_Render();
}
}
direct3D.D3D_Terminate();
return msg.wParam;
}
*Update the .cpp has been changed to show Niall's solution.
Edit:
Question:
Am I getting the LNK2005 issue because I auto-initialized my classes in their header files, considering the solution at Stack Overflow question:
VS 2010 C++ LNK2005 errors while using #pragma once and #ifndef
Which doesn't seem to work based my understanding of the solution.
Compiler
VS2013 returns:
Error 1 error LNK2005: "class Direct3D Direct3D" (?Direct3D##3V0#A) already defined in Direct3D.obj C:\Users\InfinityMachine\documents\visual studio 2013\Projects\Win32Project3\Win32Project3\Win32Project3.obj Win32Project3
Error 2 error LNK2005: "class Windows Windows" (?Windows##3V0#A) already defined in Win32Project3.obj C:\Users\InfinityMachine\documents\visual studio 2013\Projects\Win32Project3\Win32Project3\Windows.obj Win32Project3
Error 3 error LNK1169: one or more multiply defined symbols found C:\Users\InfinityMachine\documents\visual studio 2013\Projects\Win32Project3\Debug\Win32Project3.exe 1 1 Win32Project3
You declare class Direct3D... } Direct3D; and variable of the same name immediately. This would be the cause of such an error.
A variable of type Direct3D, named Direct3D (or otherwise) will be in each translation unit that includes that header, the same applies for Windows.
One possible resolution is to remove the variable declaration, another would be to move it and make it static, or in an anonymous namespace. Alternates include extern or implementing a singleton; which may be closer to the original intent.
Based on further discussions, an appropriate solution here is;
class Direct3D {};
extern Direct3D direct3D;
Then in the one of the implementation files
Direct3D direct3D;
This then declares the object as extern and provides a single instance of it.

"Unresolved external _WinMain#16" if I move WndProc to another cpp file

For a Windows application I'm trying to get CreateWindow() and WndProc() (or my versions of them) to be part of a singleton class that is created at the beginning of _tWinMain() but since trying to shift the functions to GameHandler.h and GameHandler.cpp I keep getting "unresolved external symbol _WinMain#16". They were originally global functions in main.cpp and everything was compiling fine then I decided to move them to GameHandler and ever since all I get is the unresolved external, even if I try to move them back to main.cpp.
I'm doing this in VS2010, the project was created as a Windows Application and there's no specific entry point set in properties (I double checked as every solution I've found so far says that it's because it's a console app - this isn't).
The code I currently have is shown below. The actual project has a couple of thousand lines of other code that I've left out as I don't think it's relevant (but will happily proved wrong. While the actual window creation code is related, I don't think the code itself is the problem (apart from what I left in), it's the location of GameWindowProc() &/or CreateGameWindow() or how they're called. The actual window creation code is taken from NeHe's tutorial. Trying to compile the following code only gives the aforementioned unresolved external.
main.cpp:
#include <Windows.h>
#include "GameManager.h"
#ifndef USEGMGR
bool CreateGameWindow(char* title, int width, int height, int bits, bool fullScreenFlag);
LRESULT CALLBACK GameWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
#endif
int APIENTRY _tWinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
LPTSTR lpCmdLine, int nCmdShow)
{
GameManager::Startup();
GameManager* GMgr = GameManager::GetInstance();
GMgr->SetProgramState(GAME_MODE);
while(GMgr->GetProgramState() != GAME_MODE) // Normally this would be if (State != GAME_QUIT)
{ /* do game related stuff */ }
GameManager::Shutdown();
return 0;
}
#ifndef USEGMGR
bool CreateGameWindow(char* title, int width, int height, int bits, bool fullScreenFlag)
{
// Fairly complex but flexible creation code, taken from NeHe's tutorials. Of relevant interest is:
WNDCLASS wc; // Windows Class Structure
wc.lpfnWndProc = (WNDPROC) GameWindowProc; // WndProc Handles Messages
if (!RegisterClass(&wc)) // Attempt To Register The Window Class
{
MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return false;
}
return true;
}
LRESULT CALLBACK GameWindowProc(HWND hWnd, // Handle For This Window
UINT uMsg, // Message For This Window
WPARAM wParam, // Additional Message Information
LPARAM lParam) // Additional Message Information
{
// various custom message handling, if not processed:
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
#endif
in GameManager.h:
#ifndef GAMEMANAGER_H
#define GAMEMANAGER_H
#define USEGMGR // makes CreateGameWindow() and GameWindowProc() methods in GameManager instead of global
#include <Windows.h>
enum ProgramState
{
GAME_MODE,
GAME_QUIT,
};
class GameManager
{
public:
static void Startup();
static void Shutdown();
static GameManager* GetInstance();
void Update(); // code not shown, check quit key etc
#ifdef USEGMGR
const bool CreateGameWindow(char* title, int width, int height, int bits, bool fullScreenFlag);
static LRESULT CALLBACK GameWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
#endif
void KillGameWindow(void);
const int GetProgramState() const;
void SetProgramState(const int& newMode);
private:
GameManager();
~GameManager();
GameManager(const GameManager&);
GameManager& operator=(const GameManager&);
HINSTANCE m_hInstance;
HWND m_hWnd;
HDC m_hDC;
static GameManager* s_instance;
int m_programState; // uses ProgramState enum
};
#endif
in GameManager.cpp:
#include "GameManager.h"
#include <Windows.h>
#include <assert.h>
#ifndef USEGMGR
extern bool CreateGameWindow(char* title, int width, int height, int bits, bool fullScreenFlag);
#endif
GameManager* GameManager::s_instance = NULL;
GameManager::GameManager(){}
GameManager::~GameManager(){}
void GameManager::Startup()
{
assert(s_instance == NULL);
s_instance = new GameManager;
#ifdef USEGMGR
if (! (s_instance->CreateGameWindow("Game Window", 800, 600, 32, true )) )
#else
if (! (CreateGameWindow("Game Window", 800, 600, 32, true )) )
#endif
assert("CreateGameWindow failed! Need an error here"); // Quit If Window Was Not Created - clean this up later
}
void GameManager::Shutdown()
{
assert(s_instance != NULL);
delete s_instance;
s_instance = NULL;
}
GameManager* GameManager::GetInstance(){return s_instance;}
void GameManager::Update(){/* msg handling, watch for quit key, etc */}
const int GameManager::GetProgramState() const{return s_instance->m_programState;}
void GameManager::SetProgramState(const int& newState){s_instance->m_programState = newState;}
#ifdef USEGMGR
const bool GameManager::CreateGameWindow(char* title, int width, int height, int bits, bool fullScreenFlag)
{
// Fairly complex but flexible creation code, taken from NeHe's tutorials. Of relevant interest is:
WNDCLASS wc; // Windows Class Structure
wc.lpfnWndProc = (WNDPROC) GameManager::GameWindowProc; // WndProc Handles Messages
if (!RegisterClass(&wc)) // Attempt To Register The Window Class
{
MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return false;
}
return true;
}
LRESULT CALLBACK GameManager::GameWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// various custom message handling, if not processed:
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
#endif
As you can see, I've set up some preprocessor conditionals to switch between the troublesome functions being in main.cpp or as part of GameManager. Comment out #define USEGMGR at the beginning of GameManager.h to have them as global funcs in main.cpp.
Can someone please tell me what I'm doing wrong?
Edit: removed comment about not being able to quit if you get it to run.
The WinMain function cannot be a member function of a class, even a "singleton" class.
Since it functions as the "entry point" for the program, essentially replacing the main function you'd find in a traditional C++ application, it needs to be a free global function.
The message Unresolved external _WinMain#16 is simply the compiler's cryptic way of telling you that it cannot locate the expected entry point, named WinMain (plus some name mangling).
Add
#include <tchar.h>
to the top of main.cpp so that the _tWinMain macro gets defined properly.
What happens if you don't have the macro definition is that you end up with a function named _tWinMain() (or some mangled version of the name like ?_tWinMain##YGHPAUHINSTANCE__##0PADH#Z()) in the object file, but the linker and runtime initialization code are looking for WinMain() or wWinMain(). They don't find it.
<tchar.h> defines a macro that transforms the name _tWinMain() into one of the two names everything else is looking for. You must have had something including that header before you started your refactoring (quite possibly indirectly), and lost it somehow.
Or you can dispense with the macro version and name the function WinMain or wWinMain (either one should work, regardless of whether you're building for UNICODE or not). If you do that, just remember to change the LPTSTR parameter declaration to match the one you choose.

header confusion. Compiler not recognizing datatypes

I am getting confused on why the compiler is not recognizing my classes. So I am just going to show you my code and let you guys decide. My error is this
error C2653: 'RenderEngine' : is not a class or namespace name
and it's pointing to this line
std::vector<RenderEngine::rDefaultVertex> m_verts;
Here is the code for rModel, in its entirety. It contains the varible. the class that holds it is further down.
#ifndef _MODEL_H
#define _MODEL_H
#include "stdafx.h"
#include <vector>
#include <string>
//#include "RenderEngine.h"
#include "rTri.h"
class rModel {
public:
typedef tri<WORD> sTri;
std::vector<sTri> m_tris;
std::vector<RenderEngine::rDefaultVertex> m_verts;
std::wstring m_name;
ID3D10Buffer *m_pVertexBuffer;
ID3D10Buffer *m_pIndexBuffer;
rModel( const TCHAR *filename );
rModel( const TCHAR *name, int nVerts, int nTris );
~rModel();
float GenRadius();
void Scale( float amt );
void Draw();
//------------------------------------ Access functions.
int NumVerts(){ return m_verts.size(); }
int NumTris(){ return m_tris.size(); }
const TCHAR *Name(){ return m_name.c_str(); }
RenderEngine::cDefaultVertex *VertData(){ return &m_verts[0]; }
sTri *TriData(){ return &m_tris[0]; }
};
#endif
at the very top of the code there is a header file
#include "stdafx.h"
that includes this
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include "resource.h"
#include "d3d10.h"
#include "d3dx10.h"
#include "dinput.h"
#include "RenderEngine.h"
#include "rModel.h"
// TODO: reference additional headers your program requires here
as you can see, RenderEngine.h comes before rModel.h
#include "RenderEngine.h"
#include "rModel.h"
According to my knowledge, it should recognize it. But on the other hand, I am not really that great with organizing headers. Here my my RenderEngine Declaration.
#pragma once
#include "stdafx.h"
#define MAX_LOADSTRING 100
#define MAX_LIGHTS 10
class RenderEngine {
public:
class rDefaultVertex
{
public:
D3DXVECTOR3 m_vPosition;
D3DXVECTOR3 m_vNormal;
D3DXCOLOR m_vColor;
D3DXVECTOR2 m_TexCoords;
};
class rLight
{
public:
rLight()
{
}
D3DXCOLOR m_vColor;
D3DXVECTOR3 m_vDirection;
};
static HINSTANCE m_hInst;
HWND m_hWnd;
int m_nCmdShow;
TCHAR m_szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR m_szWindowClass[MAX_LOADSTRING]; // the main window class name
void DrawTextString(int x, int y, D3DXCOLOR color, const TCHAR *strOutput);
//static functions
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
static INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
bool InitWindow();
bool InitDirectX();
bool InitInstance();
int Run();
void ShutDown();
void AddLight(D3DCOLOR color, D3DXVECTOR3 pos);
RenderEngine()
{
m_screenRect.right = 800;
m_screenRect.bottom = 600;
m_iNumLights = 0;
}
protected:
RECT m_screenRect;
//direct3d Members
ID3D10Device *m_pDevice; // The IDirect3DDevice10
// interface
ID3D10Texture2D *m_pBackBuffer; // Pointer to the back buffer
ID3D10RenderTargetView *m_pRenderTargetView; // Pointer to render target view
IDXGISwapChain *m_pSwapChain; // Pointer to the swap chain
RECT m_rcScreenRect; // The dimensions of the screen
ID3D10Texture2D *m_pDepthStencilBuffer;
ID3D10DepthStencilState *m_pDepthStencilState;
ID3D10DepthStencilView *m_pDepthStencilView;
//transformation matrixs system
D3DXMATRIX m_mtxWorld;
D3DXMATRIX m_mtxView;
D3DXMATRIX m_mtxProj;
//pointers to shaders matrix varibles
ID3D10EffectMatrixVariable* m_pmtxWorldVar;
ID3D10EffectMatrixVariable* m_pmtxViewVar;
ID3D10EffectMatrixVariable* m_pmtxProjVar;
//Application Lights
rLight m_aLights[MAX_LIGHTS]; // Light array
int m_iNumLights; // Number of active lights
//light pointers from shader
ID3D10EffectVectorVariable* m_pLightDirVar;
ID3D10EffectVectorVariable* m_pLightColorVar;
ID3D10EffectVectorVariable* m_pNumLightsVar;
//Effect members
ID3D10Effect *m_pDefaultEffect;
ID3D10EffectTechnique *m_pDefaultTechnique;
ID3D10InputLayout* m_pDefaultInputLayout;
ID3DX10Font *m_pFont; // The font used for rendering text
// Sprites used to hold font characters
ID3DX10Sprite *m_pFontSprite;
ATOM RegisterEngineClass();
void DoFrame(float);
bool LoadEffects();
void UpdateMatrices();
void UpdateLights();
};
The classes are defined within the class
class rDefaultVertex
{
public:
D3DXVECTOR3 m_vPosition;
D3DXVECTOR3 m_vNormal;
D3DXCOLOR m_vColor;
D3DXVECTOR2 m_TexCoords;
};
class rLight
{
public:
rLight()
{
}
D3DXCOLOR m_vColor;
D3DXVECTOR3 m_vDirection;
};
Not sure if thats good practice, but I am just going by the book.
In the end, I just need a good way to organize it so that rModel recognizes RenderEngine. and if possible, the other way around.
[edit]
I can literally just point to the render engine class, and it still won't recognize
#ifndef _MODEL_H
#define _MODEL_H
//#include "stdafx.h"
#include <vector>
#include <string>
#include "RenderEngine.h" //<-------pointing to render engine. still does not recognize.
#include "rTri.h"
class rModel {
public:
typedef tri<WORD> sTri;
std::vector<sTri> m_tris;
std::vector<RenderEngine::rDefaultVertex> m_verts;
std::wstring m_name;
ID3D10Buffer *m_pVertexBuffer;
ID3D10Buffer *m_pIndexBuffer;
rModel( const TCHAR *filename );
rModel( const TCHAR *name, int nVerts, int nTris );
~rModel();
float GenRadius();
void Scale( float amt );
void Draw();
//------------------------------------ Access functions.
int NumVerts(){ return m_verts.size(); }
int NumTris(){ return m_tris.size(); }
const TCHAR *Name(){ return m_name.c_str(); }
RenderEngine::cDefaultVertex *VertData(){ return &m_verts[0]; }
sTri *TriData(){ return &m_tris[0]; }
};
#endif
As others mentioned, a decoupling/refactoring is in order here - stdafx.h is not meant to hold all header files your application has.
Your problem is that renderengine.h also includes stdafx.h. This time the renderengine.h include is ignored due to #pragma once and rmodel.h is included next - at the top of renderengine.h.
The simplest thing in your case would be to:
remove renderengine.h & rmodel.h from stdafx.h
rmodel.h includes renderengine.h
... done
I can't tell for sure, but RenderEngine.h probably includes rModel.h. Then when you include stdafx.h it brings in RenderEngine.h, but before it fully processes that header it then includes rModel.h. Then inside rModel.h the include guards prevent it from including stdafx.h again and it proceeds to compile rModel.h without full knowledge of anything in RenderEngine.h.
Without understanding the full relationship of your various classes its extremely hard to suggest a fix. Most likely you'll want to carefully consider which classes are defined in which headers and use forward declarations to remove the circular dependency.
It's pretty hard to understand all your dependencies and I think that your code needs refactoring (if not rewriting). Also, rushing into a rendering engine development without any architecture building experience (as I assume) generally results in crappy unreliable code, hacks "to make it work" and other evil stuff.
Anyway, in this case, try to decompose your application's parts and distinguish them. In your case, one of possible approaches would mean putting all rendering objects / structs such as Vertex, Light, Model in another header (you could call it render.types.h or render.objects.h or something like that).
Then you should simply make your rendering engine work with these render objects. Once you're done with it, you won't need statements like std::vector<RenderEngine::rDefaultVertex> m_verts; or RenderEngine::cDefaultVertex *VertData().
Note that this would also solve your circular dependencies, because your engine would only have to know about models, models - only about vertexes and so on.
If you still face the dependency troubles, use forward declarations. Google it for full description, and just a sample for you to understand what I mean:
class ForwardDeclared;
class Object {
ForwardDeclared* member;
void Method(const ForwardDeclared& fd) { (...) }
};
// This could also resude in another file
class ForwardDeclared { (...) };