Click here to Skip to main content
15,887,027 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have a C++ MFC application which uses many COM pointers from some other libraries.
Those pointers are fetched using QueryInterface calls.
While closing my application, I get an exception log stating that some COM pointers are not yet released.

I want to know, is there any way by which I can find which COM pointers I am missing to release?

What I have tried:

I have tried calling Release on every possible pointer I could find in my application, but still the exception occurs.
Posted

With objects you do not control (e.g. COM objects internal to the libraries) there's nothing you can do.
On the other hand, with objects you do control, you may check the return value of the Release method, at least to inspect the updated reference count.
 
Share this answer
 
Comments
Saurabh Ashtaputre 24-Feb-24 4:51am    
@CPallini
Ok. Thank you very much for your help.

What is difference between objects I can control and objects I cannot control?
I mean, can you give some reference or examples?
Dave Kreskowiak 25-Feb-24 10:32am    
Did you create the instance of the object? If yes, you control it and are responsible for releasing it.
CPallini 27-Feb-24 4:14am    
You can control the lifetime of a COM object only via the Release method, hence you must have a pointer to its IUnknown interface, in order to control it.
On the other hand, a library could possibly create a COM object internally, for internal usage. Such an object is not exposed and you cannot control it (a buggy library could, for instance, 'forget' to release an internal COM object).
In practice to control releasing instances of the COM objects in the application you can use the helper template classes such as CComPtr CComQIPtr or CInterfaceList of the ATL. That allowing you to work with COM interfaces as with the regular C++ classes without afraiding that any object will not be freed. See an example:
CComPtr<IMMDeviceEnumerator> _enum;
// Create instance - Instead of __uuidof(MMDeviceEnumerator) you can use CLSID_MMDeviceEnumerator
_enum.CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL);
if (_enum) {
	CComPtr<IMMDevice> _device;
	// Initialize as the pointer argument
	_enum->GetDefaultAudioEndpoint(eRender, eConsole, &_device);
	// Query Interface
	CComQIPtr<IAudioClient> _client = _device;
	// if QueryInterface succeeded
	if (_client) {
		// Use client object
		//...
	}
	// Release object directly
	_enum.Release();
	// ANother instance assigned AddRef called
	CComPtr<IMMDevice> _device2 = _device;
	// We are not release _device and _device2 objects
	// they are freed automatically then you leave the scope
}

In some cases I create proxy one or few interfaces of the object and pass then instead to track nested object releasing and to see what interfaces queried from it and so on, but this may not be necessary in your case.

Regards,
Maxim
 
Share this answer
 
Check that you release your own COM pointers in time, so best not in the destructor but earlier like at the begin at the WM_CLOSE handler or even earlier like when the user wants to exit. The COM stuff takes some time, so be sure that it gets its time to exit properly.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900