PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [D3D] Direct3DCreate9(D3D_SDK_VERSION) + D3DDebug = Fehler


BavariaBlade
2006-11-21, 16:52:00
Hi, folgendes Problem:


// *. h datei
CComPtr<IDirect3D9> m_D3D;



// *.cpp datei
m_D3D = Direct3DCreate9(D3D_SDK_VERSION);



Verursacht ein memory leak mit der alloc id 1, aber warum?
Und warum geht DXdiag nicht mehr wenn ich es mit der debug version starten will?

Demirug
2006-11-21, 17:16:52
Klarer Fall von COM Referenz Counter Fehler.

Direct3DCreate9 liefert eine Objekt mit einem Counter von 1 zurück. Durch die Zuweisung wird ein weiterer AddRef ausgeführt. Damit wären wir bei 2. Sobald der SmartPointer den Kontext verläßt wird zwar Release aufgerufen aber das Objekt ist dann immer noch bei 1.

Anstelle der ATL Smartpointer solltest du _com_ptr_t benutzen. Die Klassenvorlage hat eine Attach Methode um dieses Problem zu umgehen.

BavariaBlade
2006-11-21, 17:56:05
Also


//*.h Datei
_com_ptr_t< _com_IIID<IDirect3D9, &IID_IDirect3D9> > m_D3D;

//*.cpp Datei
m_D3D.Attach(Direct3DCreate9(D3D_SDK_VERSION));


liefert genau den gleichen Fehler.

Das DXDiag im D3DDebug Modus eine Fehlermeldung gibt ist auch normal?
Wenn ich D3D auf "retail" stelle läuft meine App und DXDiag auch, nur eben im D3DDebug Modus nicht.

p.s.: Ich kenn mich mit COM Pointern nicht wirklich gut aus, falls du noch eine gute Infoquelle dazu hast wäre ich dir sehr dankbar.

servus BB

Demirug
2006-11-22, 20:03:54
Ist das Objekt das m_D3D enthält global? In diesem Fall könnte es passieren das die D3D DLL schon entladen wird bevor der Destructor des SmartPointers ausgeführt wird.
Welche Fehlermeldung gibt DXDiag den aus?
Für D3D muß man über COM Pointer eigentlich nicht viel wissen. Eine Einführung ist in der DX Dokumentation enthalten.

BavariaBlade
2006-12-01, 10:54:15
Ist das Objekt das m_D3D enthält global? In diesem Fall könnte es passieren das die D3D DLL schon entladen wird bevor der Destructor des SmartPointers ausgeführt wird.
Welche Fehlermeldung gibt DXDiag den aus?
Für D3D muß man über COM Pointer eigentlich nicht viel wissen. Eine Einführung ist in der DX Dokumentation enthalten.

So, danke für die Tipps. Hatte viel um die Ohren, desshalb erst jetzt ne Antwort.
Also, ich habe meinen Fehler gefunden, war eigentlich klar...
Im D3D Control Panel hatte ich immer noch "Break on alloc ID [1]" an, also hat D3D auch immer schön bei ID1 angehalten. Desshalb ging mein DxDiag nicht.

Und mein Memleak Problem konnte ich so lösen:

// *. h datei
CComPtr<IDirect3D9> m_D3D;



// *.cpp datei
m_D3D.Attach(Direct3DCreate9(D3D_SDK_VERSION));


Wie du siehst habe ich wieder die CComPtr benutzt, diese haben auch .Attach() und werden in der DX9 C++ Docu verwendet.

Gibt es trotzdem einen Grund _com_ptr_t zu bevorzugen?

Demirug
2006-12-01, 20:03:18
Wenn man comdef.h vor den DirectX Header einbindet bekommt man für die D3D Objekte automatisch passenden _com_ptr_t smart pointer. Zudem ist _com_ptr_t der vom Compiler nativ unterstützte smart pointer während der CComPtr der aus der ATL Unterstützung ist. Im Prinzip macht es keinen großen Unterschied nur ist _com_ptr_t der derzeit favorisierte Weg für nicht ATL Anwendungen.