smart pointer with d3d COM

Started by
2 comments, last by Thorris 19 years, 2 months ago
Hello, I'm currently struggling with a problem when using smart pointers with Direct3D COM objects. The smart pointer releases the COM resource when the reference count reaches 0. The problem is the order of releasing. The Direct3D device is sometimes destroyed earlier than other resources (e.g.: a surface). Now I need to find a way to ensure that the device is destroyed at last. Could anyone imagine a good solution to this problem?
Advertisement
It shouldn't matter in what order you release the COM objects. In other words,

CreateDevice(); // device ref count == 1
CreateSurface(); // device ref count == 2
surface->Release(); // device ref count == 1
device->Release(); // device ref count == 0, destroyed

or

CreateDevice(); // device ref count == 1
CreateSurface(); // device ref count == 2
device->Release(); // device ref count == 1
surface->Release(); // device ref count == 0, destroyed

Perhaps the problem is that you are releasing the device too many times (or not incrementing the reference count at the right times). CComPtr (if that is what you are using) can be a little tricky to use sometimes.

After re-reading your post it sounds like your smart pointer maintains a reference count. That is unnecessary since COM objects already have a reference count. Maybe the two are getting out of sync and that is causing your problem.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
I have recently solved (more or less) this problem by writing my own ComPtr using the enginuity articles on this site.

this is the code i am using for the pointer.
#ifndef _COM_PTR_H_#define _COM_PTR_H_#include <assert.h>template<class T>class com_ptr{protected:   T* object; public:        //Constructors - basic   com_ptr()   {      object=0;   }   //Constructing with a pointer   com_ptr(T *o)   {      object=0;      *this=0;   }   //Constructing with another smart pointer (copy constructor)   com_ptr(const com_ptr<T> &p)   {      object=0;      *this=p;   }   //Destructor   ~com_ptr()   {      if( object != NULL )	  {		  object->Release();	  }   }   //Assignement operators - assigning a plain pointer   inline void operator =(T *o)   {      if(object)object->Release();      object=o;      if(object)object->AddRef();   }   //Assigning another smart pointer   inline void operator =(const com_ptr<T> &p)   {      if(object)object->Release();      object=p.object;      if(object)object->AddRef();   }   //Access as a reference   inline T& operator *() const   {      assert(object!=0);      return *object;   }   //Access as a pointer   inline T* operator ->() const   {      assert(object!=0);      return object;   }   inline T* operator &() const   {	  assert(object!=0);	  return object;   }   inline operator T*() const   {      return object;   }   inline bool isValid() const   {      return (object!=0);   }   inline bool operator !()   {      return !(object);   }   inline bool operator ==(const com_ptr<T> &p) const   {      return (object==p.object);   }   inline bool operator ==(const T* o) const   {      return (object==o);   }   inline T** pp()   {	   return &object;   }};#endif


All reference counting is managed for you, give it a go.

ace
Hello,

thanks a lot for your detailed answers. As JohnBolton mentioned the order of releasing doesn't matter. In fact the problem came from a totally different mistake I made.

Nevertheless the hint to use the COM reference counting methods is a good idea and I will give it a try.

Ciao, Thorris.

This topic is closed to new replies.

Advertisement