• Advertisement

Archived

This topic is now archived and is closed to further replies.

C++ Class Help

This topic is 4976 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi Again... I have the library situation figured out, seems like everything is going in the right direction now. I have run into another stumbling block. I created a couple new files to accompany my win_main.cpp file, init_d3d.cpp and init_d3d.h. I am getting the error: Linking... win_main.obj : error LNK2001: unresolved external symbol "class CD3D_obj * g_D3D" (?g_D3D@@3PAVCD3D_obj@@A) Debug/Space Invaders 3D.exe : fatal error LNK1120: 1 unresolved externals I read into this and I find: Code references something (such as a function, variable, or label) that the linker can''t find in the libraries and object files. I''m assuming the problem lies in the g_D3D->D3D_init line in win_main.cpp. I have ''#extern CD3D_obj *g_D3D;'' in my .h file. I have tried to move things around in the code to get it to work. Could someone help? Below is my code.. -Dan Joseph win_main.cpp
#include <windows.h>
#include "init_d3d.h"

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

#define class_name "SpaceInvaders"

LRESULT CALLBACK WinProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam );

int WINAPI WinMain( HINSTANCE hinstance, HINSTANCE hprev, PSTR cmdline, int ishow )
{
	HWND hwnd;
	MSG  msg;
	RECT rect;

	WNDCLASSEX wndclassex = {0};

	wndclassex.cbSize           = sizeof( WNDCLASSEX );
	wndclassex.style            = CS_HREDRAW | CS_VREDRAW;
	wndclassex.lpfnWndProc      = WinProc;
	wndclassex.hInstance        = hinstance;
	wndclassex.hbrBackground    = (HBRUSH)GetStockObject( WHITE_BRUSH );
	wndclassex.lpszClassName    = class_name;
	wndclassex.hCursor          = (HCURSOR)LoadImage( NULL, MAKEINTRESOURCE( IDC_ARROW ), IMAGE_CURSOR, 0, 0, LR_SHARED );

	RegisterClassEx( &wndclassex );

	DWORD winStyleEx = WS_EX_CLIENTEDGE;
	DWORD winStyle   = WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;

	hwnd = CreateWindowEx( winStyleEx,
						   class_name,
						   "Space Invaders 3D",
						   winStyle,
						   CW_USEDEFAULT,
						   CW_USEDEFAULT,
						   800,
						   600,
						   NULL,
						   NULL,
						   hinstance,
						   NULL                    );

	if ( g_D3D->CD3D_init( hwnd ) == false )
		return EXIT_FAILURE;

	GetClientRect( hwnd, &rect );

	ShowWindow( hwnd, ishow );
	UpdateWindow( hwnd );

	while ( 1 )
	{
		if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
		{
			if ( msg.message == WM_QUIT )
				break;

			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}
	}

	return 0;
}

LRESULT CALLBACK WinProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
{
	switch ( message )
	{
		case WM_LBUTTONDOWN:
			MessageBox( 0, "Hello DirectX 9!", "Hello", MB_OK );
			return 0;

		case WM_DESTROY:
			PostQuitMessage( 0 );
			return 0;
	}

	return DefWindowProc( hwnd, message, wparam, lparam );
}
init_d3d.cpp
#include "init_d3d.h"

CD3D_obj::CD3D_obj()
{
	d3d_interface = NULL;
	d3d_device    = NULL;
}

bool CD3D_obj::CD3D_init( HWND hwnd )
{
	HRESULT               d3d_result;
	D3DPRESENT_PARAMETERS d3d_params = { 0 };
	D3DFORMAT             format     = D3DFMT_R5G6B5;

	d3d_interface = Direct3DCreate9( D3D_SDK_VERSION );

	if ( d3d_interface == NULL )
		return false;

	d3d_params.Windowed         = true;						// Windowed mode

	d3d_params.SwapEffect       = D3DSWAPEFFECT_DISCARD;
	d3d_params.BackBufferFormat = D3DFMT_UNKNOWN;

	/*
		This is some code I found.  It would be more ideal
		for our app to eventually have a configurations
		window and save the settings for resultion, and 
		windowed mode (y/n).  This is good education though.

		if( is_app_fullscreen )
		{
			pp.Windowed          = FALSE;
			pp.BackBufferWidth   = 640;
			pp.BackBufferHeight  = 480;
		}
		else
		{
			pp.Windowed          = TRUE;
		}
	*/

	d3d_result = d3d_interface->CreateDevice( D3DADAPTER_DEFAULT,
											  D3DDEVTYPE_HAL,
									 		  hwnd,
											  D3DCREATE_HARDWARE_VERTEXPROCESSING,		// There is also SOFTWARE processing...

											  &d3d_params,
											  &d3d_device                          );

	if ( FAILED( d3d_result ) )
		return false;

	return true;
}
init_d3d.h
#ifndef INIT_D3D_H
#define INIT_D3D_H

#include <d3d9.h>

class CD3D_obj
{
	public:
		CD3D_obj();		// constructor

		~CD3D_obj();	// deconstructor


		bool CD3D_init( HWND hwnd );

	private:
		IDirect3D9       *d3d_interface;
		IDirect3DDevice9 *d3d_device;

		CD3D_obj(const CD3D_obj &obj) {}
		CD3D_obj& operator =(CD3D_obj &obj) { return *this; }
};

extern CD3D_obj *g_D3D;

#endif

Share this post


Link to post
Share on other sites
Advertisement
put
CD3D_obj *g_D3D = 0;
in a source file.

extern type VariableName;
just creates a name, no storage is reserved for the data.
Then in one source file, you set aside storage for it.
This is how you create global varaibles.

It''s very similar to function prototypes.

//header
int do_something(int);

//source
int do_something(int x)
{
//actually do it
return x;
}

Share this post


Link to post
Share on other sites
Hi,

Thanks for the tip. That works now. I put the follow at the end of the init_d3d.cpp file:

CD3D_obj theD3DObj;
CD3D_obj *g_D3D = &theD3DObj;

I also put my deconstructor in, and now all is well. Thanks much!

-Dan Joseph

Share this post


Link to post
Share on other sites

  • Advertisement