Sign in to follow this  

COM Interface Question

This topic is 4843 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

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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

This topic is 4843 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this