COM Interface Question

Started by
5 comments, last by Muhammad Haggag 19 years, 7 months ago
Okay, I’ve made a class called root that contains a pointer to the IDirect3DDevice9 interface. The class is just used as a parameter that contains methods for manipulating render states, transformations, and rendering primitives. The problem is that I want to send the class as a parameter to another class that used it for drawing stuff. The roots’ device pointer is initialized by pointing it to the main device interface via root::device_pointer = mainwindow::device_pointer. Should I use AddRef( ) after this and then call the Release( ) when the root has terminated? Or better yet, would those two COM methods interfere with the main device pointer.
Take back the internet with the most awsome browser around, FireFox
Advertisement
I usually don't really get very picky about AddRef() and Release(). Usually, the reference count on the IDirect3DDevice9 is only increased upon creation (CreateDevice()), and then I only need one Release() call to destroy it (of course other D3D and D3DX interfaces will increase and decrease the reference count).

So, in my opinion, you don't really need to go through the trouble of increasing and decreasing the reference counter when only copying a pointer.
Dustin Franklin ( circlesoft :: KBase :: Mystic GD :: ApolloNL )
Generally, you should call AddRef every time you make a copy of a COM object pointer. It is most important if the the copy persists across scope boundaries. It is least important if Release would be called right away or the object persists for the entire duration of the program.

In your case, if the copy lasts only long enough to send it to the function, then there is not much reason to call AddRef, since you will be calling Release soon after.
void foo(){    root    r;    ...    r.device_pointer = mainwindow.device_pointer;    r.device_pointer->AddRef();  // Not that important because it is released two lines later.    bar( r );    r.device_pointer->Release();    r.device_pointer = NULL;    ...} 
On the other hand, if the copy persists across scope boundaries (in a global, for example), then it is important to use AddRef/Release because you don't know how the copy might be used.
root    r; void foo(){    ...    r.device_pointer = mainwindow.device_pointer;    r.device_pointer->AddRef();    ...}void bar(){    ...    r.device_pointer->Release();    r.device_pointer = NULL;    ...} 
In this case it might be better to only allow setting the value via an accessor so that you call AddRef in the accessor. You would also implement a copy constructor and assignment operator in case the class instance is copied or assigned, and call Release in the destructor.

Finally, consider using CComPtr which is a smart pointer that automatically maintains the reference count.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Well the root is used for graphical functions, as I said before. It is sent to the plug-in class two times. Once during initialization and once during render time. The class looks like this.

class ISprout{public:	ISprout( );	virtual ~ISprout( );	virtual HRESULT InitSprout( IRoot** ) = 0;	virtual HRESULT DrawSprout( IRoot** ) = 0;	virtual HRESULT KillSprout( ) = 0;};


The sprout class is my little plug-in draw-something class. I’m just trying to separate the drawing part of my application from the initialization and data manipulation part. The root class looks like this.

class IRoot{public:	IRoot( );	~IRoot( );	HRESULT SetForegroundColor( DWORD );	HRESULT SetBackgroundColor( DWORD );	HRESULT SetTexture( UINT, ITexture );HRESULT SetTextureState( UINT, TEXTURESTATE, LPVOID );	HRESULT SetFillMode( FILLMODE );HRESULT SetRenderState( RENDERSTATE, LPVOID );	HRESULT SetLightDiffuse( UINT, COLOR );	HRESULT SetLightAmbient( UINT, COLOR );	HRESULT SetLightPosition( UINT, VECTOR );	HRESULT SetLightDirection( UINT, VECTOR );	HRESULT SetLightType( UINT, LIGHTTYPE );	HRESULT SetLightRange( UINT, FLOAT );	HRESULT PrintText( UINT, UINT, LPCSTR );	HRESULT DrawPrimitive( PRIMITIVETYPE, UINT, LPVOID );private:	LPDIRECT3DDEVICE9 m_lpD3DDevice;};


It’s not much for now, but it will be growing. I want the root to act as a HDC except it will be using Direct3D. It will only be use for those two functions of the ISprout class. I thought, maybe creating a separate class for the init method, but I’m not sure. I just wanted to know if I would screw up Direct3D if I used the AddRef and Release functions. Oh yah, the sprout methods will be called once a frame, well the DrawSprout will be.
Take back the internet with the most awsome browser around, FireFox
Use ATL's CComPtr and CComQIPtr template wrappers and never worry about AddRef() and Release() again.
I’m using MFC though. Won’t ALT and MFC conflict?
Take back the internet with the most awsome browser around, FireFox
Quote:Original post by sakky
I’m using MFC though. Won’t ALT and MFC conflict?

You can use the smart pointers without other ATL functionality. They're defined in the file <atlbase.h>

I've written a small blurb about them here

This topic is closed to new replies.

Advertisement