Problem mit Debugger



  • Hi zusammen!

    Nachdem ich in VC++ 2008 nun alle Fehler so weit behoben hatte, macht der Debugger mir jetzt Probleme.
    Das Beispiel unten ist zwar eine DirectX Anwendung, aber ich habe das Problem in dieses Unterforum geschrieben, weil ein Problem mit dem VC++ Debugger vorliegt.
    Ich habe den Code unten aus einem Buch für Spieleprogrammierung übernommen und für meine Zwecke abgeändert.

    # include <stdio.h>
    # include <stdarg.h>
    # include <windows.h>
    # include <commctrl.h>
    # include <d3dx9.h>
    # include <dinput.h>
    # include "d3dfont.h"
    #include <d3d9.h>
    # include "resource.h"
    HINSTANCE balance_instance;
    HWND balance_window;
    
    class directx
    	{
    	public:
    		LPDIRECT3D9 d3d;
    		LPDIRECT3DDEVICE9 device;
    		D3DPRESENT_PARAMETERS d3dpp;
    
    		int init();
    		void adjust(int breite, int hoehe);
    	};
    
    int directx::init()
    	{
        D3DDISPLAYMODE d3ddm;
    	D3DDEVTYPE devtype;
    	D3DCAPS9 caps;
    
    	d3d = Direct3DCreate9( D3D_SDK_VERSION);
        if( !d3d)
            return 0;
    
        if( d3d->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm) < 0)
            return 0;
    
        ZeroMemory( &d3dpp, sizeof(d3dpp));
        d3dpp.Windowed = TRUE;
        d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
        d3dpp.EnableAutoDepthStencil = TRUE;
        d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
    	d3dpp.BackBufferFormat = d3ddm.Format;
    
    	if( d3d->GetDeviceCaps( D3DADAPTER_DEFAULT,  D3DDEVTYPE_HAL, &caps) < 0)
    		{
    		MessageBox( balance_window, "Kein HAL-Device - das wird langsam!", "Balance-Meldung", MB_OK | MB_ICONWARNING | MB_SETFOREGROUND);
    		devtype = D3DDEVTYPE_REF;
    		}
    	else
    		devtype = D3DDEVTYPE_HAL;
    
        if( d3d->CreateDevice( D3DADAPTER_DEFAULT, devtype, balance_window, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &device) < 0)
            return 0;
        return 1;
    	}
    
    void directx::adjust( int breite, int hoehe)
    	{
        D3DXMATRIX proj;
    
        d3dpp.BackBufferWidth  = breite;
        d3dpp.BackBufferHeight = hoehe;
    	device->Reset( &d3dpp);
    	device->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE);
    	device->SetRenderState( D3DRS_AMBIENT, 0xffffff);
    	D3DXMatrixPerspectiveFovLH( &proj, D3DX_PI/4, ((float)breite)/hoehe, 1.0f, 500.0f);
    	device->SetTransform( D3DTS_PROJECTION, &proj);
    	}
    
    directx mein_directx;
    
    class objekt
    	{
    	private:
    		LPD3DXMESH mesh;
    		D3DMATERIAL9 *materialien;
    		DWORD anz_mat;
    		LPDIRECT3DTEXTURE9 *texturen;
    	public:
    		objekt();
    		void load( char *xfile);
    		void draw();
    		~objekt();
    	};
    
    objekt::objekt()
    	{
    	mesh = NULL;
    	materialien = NULL;
    	anz_mat = 0;
    	texturen = NULL;
    	}
    
    objekt::~objekt()
    	{
    	unsigned int i;
    
        if( materialien) 
            delete[] materialien;
    
        if( texturen)
    		{
            for( i = 0; i < anz_mat; i++ )
    			{
                if( texturen[i])
                    texturen[i]->Release();
    			}
            delete[] texturen;
    		}
        if( mesh)
            mesh->Release();   
    	}
    
    void objekt::load( char *xfile)
    	{
        LPD3DXBUFFER buf;
    	D3DXMATERIAL* mat; 
    	DWORD i;
    
        D3DXLoadMeshFromX( xfile, D3DXMESH_SYSTEMMEM, mein_directx.device, NULL, &buf, NULL, &anz_mat, &mesh);
    
    	mat = (D3DXMATERIAL*)buf->GetBufferPointer();
        materialien = new D3DMATERIAL9[anz_mat];
        texturen  = new LPDIRECT3DTEXTURE9[anz_mat];
    
        for( i=0; i<anz_mat; i++)
    		{
            materialien[i] = mat[i].MatD3D;
    		materialien[i].Ambient.r = 1.0f;
    		materialien[i].Ambient.g = 1.0f;
    		materialien[i].Ambient.b = 1.0f;
    		if( D3DXCreateTextureFromFile( mein_directx.device, mat[i].pTextureFilename, &texturen[i]) < 0) 
                texturen[i] = NULL;
    		}
        buf->Release();
        }
    
    void objekt::draw()
    	{
    	unsigned int i;
    
    	for( i=0; i < anz_mat; i++ )
    		{
    		mein_directx.device->SetMaterial( &materialien[i]);
            mein_directx.device->SetTexture( 0, texturen[i]);
    		mesh->DrawSubset( i);
    		}
    	}
    
    class objekte
    	{
    	public:
    		objekt obj[5];
    		void lade_objekte();
    	};
    
    void objekte::lade_objekte()
    	{
    	obj[4].load( "saebel.x");
    
    	};
    
    objekte meine_objekte;
    
    class balance
    	{
    	private:
    		D3DXVECTOR3 hier_bin_ich;
    		D3DXVECTOR3 da_gucke_ich_hin;
    	public:
    		int init();
    		void start();
    		void render();
    	};
    
    void balance::start()
    	{
    
    	hier_bin_ich = D3DXVECTOR3( 0.0f, 3.5f*3, -3.5f*3);
    	da_gucke_ich_hin = D3DXVECTOR3( 0.0f, 0.0f, 0.0f);
    	}
    
    int balance::init()
    	{
    	if( !mein_directx.init())
    		return 0;
    	meine_objekte.lade_objekte();
    	return 1;
    	}
    
    void balance::render()
    	{
    	int z, s;
    	D3DXMATRIX world;
    	D3DXMATRIX view;
    
        mein_directx.device->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(255,255,255), 1.0f, 0 );
        mein_directx.device->BeginScene();
    
    	D3DXMatrixLookAtLH( &view, &hier_bin_ich, &da_gucke_ich_hin, &D3DXVECTOR3( 0.0f, 1.0f, 0.0f));
    	mein_directx.device->SetTransform( D3DTS_VIEW, &view);
    
    		    D3DXMatrixTranslation( &world, 3, 0.0f, 3); 
    		    mein_directx.device->SetTransform( D3DTS_WORLD, &world);                  
    			meine_objekte.obj[4].draw();
    
    	D3DXMatrixTranslation( &world, 3, 
    		                      1.0f, 3);
        mein_directx.device->SetTransform( D3DTS_WORLD, &world);
    
        mein_directx.device->EndScene();
        mein_directx.device->Present( NULL, NULL, NULL, NULL);
    
    }
    
    balance mein_spiel;
    
    LRESULT CALLBACK balance_windowhandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    	{
    	switch( msg) 
    		{
    	case WM_COMMAND:
    		switch( LOWORD(wParam)) 
    			{
    		case IDM_EXIT:
    			PostMessage( hWnd, WM_CLOSE, 0, 0);
    			return 0;
    			}
    		break;
    
        case WM_PAINT:
            mein_spiel.render();
            ValidateRect( hWnd, NULL);
            break;
        case WM_SIZE:
    		if( wParam != SIZE_MINIMIZED)
    			mein_directx.adjust( LOWORD(lParam), HIWORD(lParam));
            break;
    
    	case WM_DESTROY:
    
    		PostQuitMessage( 0);
    		return 0;
    		}
        return DefWindowProc(hWnd, msg, wParam, lParam);
    	}
    
    int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
    	{
    	MSG msg;
        HACCEL acc;
    	WNDCLASSEX wcx;
    
    	balance_instance = hInst;
    
    	wcx.cbSize          = sizeof( wcx); 
    	wcx.lpszClassName	= "Balance";
    	wcx.lpfnWndProc	    = balance_windowhandler;
    	wcx.style			= CS_VREDRAW | CS_HREDRAW;
    	wcx.hInstance		= hInst;
    	wcx.hIcon			= LoadIcon(hInst, MAKEINTRESOURCE( IDI_BALANCE));
    	wcx.hIconSm		    = LoadIcon(hInst, MAKEINTRESOURCE( IDI_BALANCE));
    	wcx.hCursor		    = LoadCursor(NULL, IDC_ARROW);
    	wcx.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
    	wcx.lpszMenuName	= MAKEINTRESOURCE( IDR_MENU);
    	wcx.cbClsExtra		= 0;
    	wcx.cbWndExtra		= 0;
    
    	if( !RegisterClassEx( &wcx))
    		return 0;
    
    	acc = LoadAccelerators(hInst, MAKEINTRESOURCE( IDR_ACCEL));
    
    	balance_window = CreateWindowEx(0, TEXT( "Balance"), TEXT( "Balance"), WS_OVERLAPPEDWINDOW, 
    		                                     CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL);
    
    	if( !balance_window ) 
    		return 0;
    
    	if( !mein_spiel.init())
    		{
    		MessageBox( balance_window, "Direct3d konnte nicht initialisiert werden", "Balance-Meldung", MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
    		return 0;
    		}
    
    	ShowWindow( balance_window, nCmdShow);
    	mein_spiel.start();
        while( TRUE)
    		{
            if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE))
    			{
                if( GetMessage( &msg, NULL, 0, 0 ) == 0)
                    return 0; 
    
                 if( TranslateAccelerator( balance_window, acc, &msg) == 0)
    				{
                    TranslateMessage( &msg); 
                    DispatchMessage( &msg);
    				}
    			}
    		}
        return 0;
    	}
    

    In dem Projekt soll ein Fenster mit DirectX Device hergestellt werden. Anschließend wir ein Mesh(Saebel.x) geladen.
    Der Debugger zeigt mir für die Zeilen 122 und 135 Folgendes an:

    Eine Ausnahme (erste Chance) bei 0x004014ed in Balance.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xcccccccc.
    Unbehandelte Ausnahme bei 0x004014ed in Balance.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xcccccccc.
    Eine Ausnahme (erste Chance) bei 0x0040161e in Balance.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xcccccccc.
    Unbehandelte Ausnahme bei 0x0040161e in Balance.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xcccccccc.
    

    Er scheint also Probleme mit der Variable "buf" zu haben.
    Nur ist meines Erachtens alles richtig deklariert.
    Wenn ich auf mat in Zeile 122 klicke, wird mir Folgendes angezeigt:

    mat = 0xcccccccc {MatD3D={...} pTextureFilename=??? }
    +MatD3D = {Diffuse={...} Ambient={...} Specular={...} ...}
     pTextureFilename = CXX0030: Fehler: Ausdruck kann nicht ausgewertet werden
    

    Kann mir einer von euch vielleicht sagen, worum es sich bei dem Problem handelt und wie man es löst?
    Bisher habe ich in diesem Projekt alle Probleme lösen können, bei dem oben weiss ich aber nicht weiter.



  • buf wird vermutlich noch gar nicht initialisiert sein...



  • Aber in Zeile 116 steht doch

    LPD3DXBUFFER buf;
    

    und die Funktionen für Materialien sind doch in der objekt Klasse.



  • Aber auf was soll denn buf zeigen ??

    Wie _matze schon sagte:
    Er wird da angelegt, aber es wird nicht gesagt, was in buf stehen soll.
    Setz mal nen Breakpoint zwischen den Zeilen 116 und 122 und zeig mit dem Cursor mal auf buf, da wird man sehen, dass nix in buf steht.

    Es ist doch ein Pointer, deswegen ja auch LPD3DXBUFFER 👍

    Hast du auch eine Warnung vom Compiler dazu gekriegt ??



  • Ja , der Debugger zeigt dann folgenden Inhalt für buf an:

    buf = 0xcccccccc
    +IUnknown = {...}
    +__vfptr = CXX0030: Fehler: Ausdruck kann nicht ausgewertet werden
    

    Vom Compiler bekomme ich keine Warnung, mit dem Compiler hatte ich ja schon vorher Probleme, die jetzt aber behoben sind.
    Der Buffer soll die Texturinformationen des Meshs aus Zeile 120 an die Variable mat weitergeben, damit später mit dieser die Texturen geladen werden.



  • Ach ja, falls es noch wichtig ist:
    Wenn ich beim Debuggen auf das buf in Zeile 116 gehe(bei LPD3DXBUFFER),dann wird Folgendes angezeigt:

    buf = 0x0056fdb0
    +IUnknown = {...}
    +__vfptr = 0x00151434
    +[0x0] = 0x0017b963
     [0x1] = 0x00181a69
     [0x2] = 0x0017b6d2
    

    Und wie ich schon geschrieben habe, wird in Zeile 122 bei buf->GetBufferPointer
    Folgendes angezeigt:

    buf = 0xcccccccc
    +IUnknown = {...}
    +__vfptr = CXX0030: Fehler: Ausdruck kann nicht ausgewertet werden
    

    Zwischen Zeile 116 und 122 werden noch andere Variablen angegeben und der Mesh Geladen:

    D3DXMATERIAL* mat;
        DWORD i;
    
        D3DXLoadMeshFromX( xfile, D3DXMESH_SYSTEMMEM, mein_directx.device, NULL, &buf, NULL, &anz_mat, &mesh);
    

    Bei der Mesh_Lade_Funktion wird für buf genau das selbe angezeigt wie in Zeile 116.
    Was ich komisch finde, ist, dass der Originalcode funtkioniert, meine abgeänderte Version aber nicht, obwohl ich an der Objekt-Funktion nichts geändert habe. Hier ist doch eigentlich alles beim alten.



  • Ok, du hast nen Pointer buf vom Typ LPD3DXBUFFER

    wenn du in Zeile 116 mit dem Cursor drüber gehst, ist es ja logisch, dass da diese Werte gezeigt, da der Pointer ja auf nix zeigt (er ist nicht initialisiert)!

    Wenn du nen Breakpoint in Zeile 122 hast und da auch dieselben Werte wie in 116 gezeigt werden, dann kann eig nur noch ein Fehler bei der D3DXLoadMeshFromX-Funktion sein, weil nach der Rückkehr der Funktion sollte ja was in buf stehen (du übergibtst ja die Adresse des Pointers beim Aufruf)

    Lass dir mal Anzeigen, was in den anderen Variablen wie z.B. anz_mat steht oder ob da dasselbe angezeigt wird.

    gesse385 schrieb:

    Was ich komisch finde, ist, dass der Originalcode funtkioniert, meine abgeänderte Version aber nicht, obwohl ich an der Objekt-Funktion nichts geändert habe. Hier ist doch eigentlich alles beim alten.

    Aber hier ist, wie du siehst, ein Fehler versteckt. 👍

    EDIT:
    Nehm doch einfach mal keinen Pointer, sondern ne normale Variable und leg die aufm Stack an und probiers damit mal !



  • Ich hab den Fehlerr gefunden:

    Wenn man buf in Zeile 116 auf NULL setzt:

    LPD3DXBUFFER buf = NULL;
    

    und den Debugger Stop entfernt(hab ich erst vergessen 😡 ), dann läuft das Programm perfekt. Jetz muss ich nur noch eine Kamerasteuerung einbauen, dann ists perfekt.
    Nochma Danke für die Tipps.


Anmelden zum Antworten