I am using the COM CoCreateInstanceEx API to create an instance of a specific class on a local computer.
I am using the same function again to get the instance which was created earlier but it creates a new instance.
Is it the right way to get the object of the class from running instance or should I use any other method ?
C++ Code snippet:
HRESULT nResult = CLSIDFromProgID(OLESTR("ABC"), &clsid);
MULTI_QI mqi[1];
mqi[0].pIID = &IID_IUnknown;
mqi[0].pItf = NULL;
mqi[0].hr = 0;
nResult = CoCreateInstanceEx(clsid, NULL, CLSCTX_LOCAL_SERVER, NULL, 1, mqi);
IUnknown *pUnk = mqi[0].pItf;
Is it the right way to get the object of the class from running instance or should I use any other method ?
No it is not. CoCreateInstanceEx delves into the depths of the COM factory mechanics to get the factory for the object required and creates a new one.
To get a "copy" of the same instance you last used, there are some options to choose from;
Call AddRef() on the first created object to increment the COM objects reference count for the copy of the object pointer you are about to make. You then use that pointer until it is no longer required, then call Release(). The Release() decrements the reference count and, if it is the last reference, the COM object can destroy itself. This does not perform a deep copy of the object and its contents.
If you have access to the code, you make the COM object a singleton or otherwise modify the lifetime as you require it. If the COM object code uses the ATL, there a several macros here that can assist, in particular DECLARE_CLASSFACTORY_SINGLETON.
Create a Clone() method on the COM object that performs the deep copy, the exact mechanism here would depend on the object itself, but typically it is nothing more than the usual coping the appropriate data fields.
Frankly though, unless this is an exercise in learning how COM works, don't use naked pointers and try to manage the objects lifetime manually. Use the ATL classes, in particular ATL::CComPtr<> and it takes care of these issues as you would expect it to.
You don't specify in too much detail how and where the object is created. There are more advanced object registration and retrieval techniques that allow a greater level of control over the objects creation, lifetime and use. You could explore these if they are suitable;
The active object mechanisms of GetActiveObject et al.
If the object being used registers itself with the ROT (the running object table), you could also explore the using the ROT.
Related
If I create the pointer of any COM interface and then assign it to an object of CComPtr of same COM Interface do I need to release the original COM pointer?
ISomeComInterface* pSomeComInterface = new CSomeComInterfaceImplemented();
CComPtr<ISomeComInterface> cptrSomeComInterface = pSomeComInterface;
// ....
// Do I need to Release original COM Pointer.
pSomeComInterface->Release();
Yes, you may need release the previous pointer;
CComPtr::operator =
This operation AddRefs the new object and releases the existing object, if one exists.
From MSDN. CComPtr is used to manage the lifetime of the COM object (it applies the RAII idiom to COM objects) - it manages the reference count itself.
However, the technique you are using to create the COM object is unusual and it seems to not perform the AddRef(); hence in this case the Release() would not be needed.
The common manner to create a COM object with CComPtr is to use the CoCreateInstance method of CComPtr. In which case the AddRef() and Release() methods are managed by the CComPtr and should not be called by your client code.
CComPtr takes care of reference count of its internal interface pointer, managed by the instance of the class. It has no effect on reference counts of other pointers. That is, having assigned the pointer to the variable, you can be sure that CComPtr's internal pointer is AddRef'ded and Release'd as necessary, however you should take care of your raw interface pointer variable pSomeComInterface yourself and make explicit Release call.
This depends on how the COM object constructor initializes the reference count. Most likely it sets it to zero so you don't need an extra Release() call. CComPtr will then take care of the object.
Look into how the COM object initializes the reference count to be sure. It's not illegal to set the reference count to anything other than zero, the only requirement is that once the object pointer is returned to COM client the reference count is set to one and ownership is so passed to the client. Strictly speaking because you new the object instead of calling CoCreateInstance() or calling a method of a COM object you're not guaranteed any specific value.
So the following could be legal if reference count is set to one in object constructor:
HRESULT ComMethod( Type** result )
{
if( result == 0 ) {
return E_POINTER;
}
//refcount set to 1 in constructor,
//so no AddRef() call
*result = new Type();
return S_OK;
}
Using COM you use CoCreateInstance to create an object.
Is there a way of destroying it totally so the next part of the unit test can start from afresh?
Everyone holding a referenced COM interface pointer is guaranteed that the object is alive, so without knowing everyone who holds interface pointers to your COM object, and being able to ask to release you cannot make sure the object is destroyed.
You certainly can try
for(; ; )
{
if(pFoo->Release() == 0)
break;
}
However even with this you (a) can get dead loop, (b) those referencing your object will get access violation/undefined behavior once they try to access destroyed object (they still expect the referenced object to be alive).
Another approach is that you use a wrapper object and manage the real COM object internally without exposing it. And you forward methods calls from wrapper to inner object. Then you can ask your wrapper to release the internal references and this typically leads to destruction of the inner object.
I wrote a simplistic DBResourceMonitor class which is used by a set of database classes. When an instance of one of my database classes is created, it registers itself, and when destroyed, it unregisters itself with a singleton instance of DBResourceMonitor. When the application terminates, that global instance of DBResrouceMonitor is destroyed, which checks to make sure that there are no remaining registered instances of any of the classes that it monitors (i.e. that for every register, a unregister was called), and issues a TRACE output and ASSERT if there was a mismatch.
This is all well and good... until I put a couple of these database objects as members of my global application object. Hence, both the global application object, and the DBResourceMonitor are global singletons, and the application is the first to be constructed, hence the last to be destroyed, and hence when DBResrouceMonitor is destroyed, the members of the app object have yet to be unregistered, and so it throws an error indicating that there were mismatched register/unregister calls.
As far as I am aware, there is no way to ensure that the DBResrouceMonitor is constructed before the application object (and therefore destroyed afterwards).
Is this correct? Is there a clever way around that, or a way to rethink the above so that I can still track whether everything was taken care of before the final thread terminates?
Instead of having the objects register/deregister themselves with a singleton, you need to store the references to those objects in a collection property of the Singleton. So instead of doing:
var x = new MyDBObject();
you would use a factory pattern like:
var x = DBResourceMonitor.GetDBObject();
and somewhere in DBResourceMonitor you could manage a collection of MyDBObjects
MyDBObject GetDBObject()
{
//construct and save a MyDBObject or retrieve one from a list.
}
You could let the database object be the same as the resource monitor, by having a base class that "registers" the database object in its constructor, and "deregister" it in the (virtual) destructor. This way you can just create the object and not worry about singletons or extra monitor classes. The collection of objects would of course be a private static member in this base class, possibly protected in case of you using multi-threading.
I would also use std::unique_ptr instead of raw pointers, or possibly std::shared_ptr.
I have a case in my application where I need to create a new object dynamically based on what type info I get back from an external source. Basically, I have class A that handles this task. The class will either create class B, C, or D, etc. (say B is the base and C and D are derived types). Then I want to pass this object to an existing interface that is full of methods that expect a reference parameter of type B. Eventually this dynamically allocated object is stored in a boost::shared_ptr member object of another class (I use the reset() method on the shared_ptr). So at that point the memory is being managed by someone.
Basically it seems like this is bad design to me (that I'm passing this dynamically allocated object all over the place, dereferencing it at one point and then getting the pointer to it again later). On the other hand, I don't want to change several methods of an interface to take a pointer rather than a reference. I would like to leave that interface alone and dereference the pointer when I'm passing the object on to the interface for further processing. I read somewhere that when you have a method that takes a reference parameter, you're saying "I'm not concerned about memory management here" and "this object will be initialized - i.e. can't be NULL". The object was originally created on the heap though and will eventually be "owned" by another class that will manage its memory. Is still OK to have these interface methods take reference parameters in this case?
I think that the primary goal of design in terms of object usage and lifetime should be that the ownership of the object is clear and well-understood at all times. The creation and deletion is ideally handled in only one place, or is clearly signposted when you are creating and handing-off somewhere else - again, that should be done only in one place.
My preference would be that until the object is owned outright by some piece of code, then pointers should be used. Once it is owned, then the owner can pass it on as a reference.
With pointers, it's okay to interpret as "here's an object - does anyone want it?"
With references, you're saying "here's MY object - you can use it"
But if that forces you to makes the rest of your code ugly and confusing, then maintaining that ideal is not worth the price you pay. If you can at least make the creation and hand-off look clean, then you can hide the quirky stuff in some other (well-documented) part of the code...
B * myInst = A::BFactory( current_state_of_universe );
bool bSubmitted = SubmitForMagic( myInst );
if( !bSubmitted ) delete myInst;
I came across a leak in a Direct3D application of mine, and I ended up correcting it, but I think the cause of the leak was due to my misunderstanding of how Direct3D handles its memory and interfaces.
I haven't been able to find a definitive article/tutorial on it (please provide one if you have one), but from what I've gathered, it works as such:
Every time you call a Get method, the number of references for the object returned is incremented. So if I call GetRenderTarget, the surface being rendered to has its reference count incremented.
Calling Release on the interface decrements its reference count. These first two points combined essentially mean: every time you get an interface, release it after you're done with it.
When the reference count reaches 0, the instance is deleted.
I'm not entirely sure if this is correct, but it seems to work in practice. If someone could clarify/confirm how it works, that'd be great.
P.S, are there any safeguards implemented in releasing interfaces? Calling Release any number of times on the back buffer doesn't seem to do any damage (which is a good thing, but I'm not sure why it doesn't).
Direct3D is based on COM, which is a technology that's at least 15 years old. Seems many people claim COM is dead and for that reason many overlook it, but reality is that there are many things in windows including Direct3D and MS's new Media Foundation that are all based on COM.
I strongly suggest you take a look at general COM programming. There are plenty of books and resources, but many of them are rather old but that's ok because the root of the technology hasn't changed for a very long time.
Basically what you've observed is interface reference counting. COM is based purely on accessing objects via interfaces, which all derive from the base interface, IUnknown. IUnknown implements methods AddRef() and Release() and it is the responsibility of your application to call AddRef() whenever you store a local copy of a pointer and to call Release() whenever that local copy is no longer needed.
When you have methods with interface out parameters (i.e. IFoo** ppObj ), that means the callee is giving you back an interface and now that you have it, it is still your responsibility to call Release() whenever you are done with it.
Once you get the hang of it, I'd suggest you start using CComPtr smart class for storing local and member variables (still pass raw interface values between function calls, no need for smart pointer parameter types). It will take care of all your reference counting. Also don't make it a practice of calling release "any number" of times. It might work today because the object is implemented as a singleton, or maybe something else is holding on to it, but that might change with next patch or next release. Always follow the rules. If you have an interface, when you don't need it call Release() exactly once. If you made a copy of interface pointer, make sure to call AddRef() exactly once.
The application of addref/release semantics is much wider than COM technology. There is simple rule one CreateObject() (or CreateTexture, or GetRenderTarget, or GetBackBuffer, etc...) have to be confronted with one Release(), one AddRef() have to be confronted with one Release().
In COM IUnknown::Release() returns number of references to object. It may delude you and you can think:
"Hm... I just call Release() until it return 0 and I will have no leaks. ???? PROFIT!!!!!111" <-- That is wrong! AddRef might be called by Direct3D itself or by 3rd_party library you pass this object to, or something else outside your app. One Release for one AddRef. You should call Release when you don't need object anymore, don't waste system resources.
You said:
Calling Release any number of times on the back buffer doesn't seem to do any damage
That means nothing. May be The Universe like you so much or you just too lucky to not get exceptions from D3D.
Smart pointers (such as CComPtr) could make your life much easier if you will use them. In this case you don't need to call Release explicitly, it is called in CComPtr dtor if it is assigned to some object.
void get_surface(IDirect3DDevice9 *pDevice)
{
IDirect3DSurface9 *surf0;
IDirect3DSurface9 *surf1;
CComPtr<IDirect3DSurface9> surf2;
CComPtr<IDirect3DSurface9> surf3;
CComPtr<IDirect3DSurface9> surf4;
pDevice->GetRenderTarget( 0, surf0 ); // surface reference counter incremented, you should call Release() for this
surf1 = surf0; // surface reference count is not incremented, you shouldn't call Release() for this
pDevice->GetRenderTarget( 0, surf2 ); // surface reference counter incremented
CComPtr<IDirect3DSurface9> surf3 = surf0; // surface reference counter incremented
surf0->Release(); // release for pDevice->GetRenderTarget( 0, surf0 );
surf2.Release(); // .Release() used not ->Release() - it is important
surf4.Release(); // nothing happens because surf4 == 0
} // surf3.Release() is called in surf3 destructor
Also you may #define D3D_DEBUG_INFObefore including direct 3d headers and switch to debug d3d runtime. It is helpful in finding leaks in d3d app.
May the CComPtr Force be with you.
D3D objects are COM objects, and they use a basic reference counting system to manage the lifetime of the object. (See wikipedia for more info about the Component Object Model, or the MSDN article Managing Object Lifetimes)
The reference count is modified purely through the AddRef/Release methods, and certain other functions call those methods.
Creating the object as well as calling certain Get methods that return an object derived from the IUnknown class will call AddRef internally to increment the reference count, so you will need to call Release for each call when you are finished with the object.
If you pass the object to another function or class that stores a copy of the point (even temporarily) that class/function should call AddRef to ensure that the object is not freed while it is using it (and Release to signal it is done).
When the reference counter reaches 0 from a call to Release the object is signalled that it may be a good time to delete the held resources, but it may not happen immediately. There is also no protection for calling Release multiple times. The reference counter will not become negative, but it will not perform any other sanity checking (because it can't really) so you can cause application instability by trying to release references you don't hold.
Yes, you are correct. This is called reference counting and it ensures that objects are alive as long as they are being used, and no longer. You can use a variety of smart pointers to enforce this rule- both shared_ptr and (C++11) unique_ptr allow for custom deleters to call Release(). This makes it easy to control the lifetime of Direct3D objects just like you would for any other object in your application. You don't need to start including ATL libraries and CComPtr to use smart pointers with COM interfaces.