CodeSteps

Python, C, C++, C#, PowerShell, Android, Visual C++, Java ...

COM – Creating a COM Component using C++ – Inside CoCreateInstance

As we discussed in our previous articles, COM’s CoCreateInstance function is used to create instances for COM classes.

What is happening inside the CoCreateInstance function?

When the client program calls CoCreateInstance to create an instance of COM class:

  • It actually internally calls another function CoGetClassObject
  • CoGetClassObject checks the registry entries for CLSID which was passed through our CoCreateInstance function.
  • If CoGetClassObject finds the location of the DLL associated with the CLSID, it calls the CoLoadLibrary function to load the DLL into memory.
  • After the DLL is loaded into the memory, CoGetClassObject will get the address of DLL’s exported function DllGetClassObject to create an instance of the class.

Till now it seems fine. We have implemented our COM class the same way as the COM library expected.

But why our client application is failing to create an instance of our HelloComponent class? Let us re-check the error our test application is displaying. Our test application is displaying a “No such interface supported” error message. This means, our COM component is unable to identify the interface. We have implemented IUnknown and IHello interfaces in our components. And we are requesting to create an instance of our HelloComponent through IID_IHello. We have tested this and it is working fine when we call the DllGetClassObject function directly, without calling CoCreateInstance. It seems our CoCreateInstance function is playing something tricky here which is what we aren’t expecting. It seems it is passing some other IID instead of IID_IHello to DllGetClassObject. That could be the reason our component’s QueryInterface function is failing and returning the E_NOINTERFACE error.

Then we need to figure out why CoCreateInstance is playing a tricky part here and what interface IID it is passing through DllGetClassObject?

To identify, what interface CoCreateInstance is requesting, just we will modify our QueryInterface function to display the requested interface ID. Our modified code looks like below:

HRESULT CHelloComponent::QueryInterface(REFIID riid, LPVOID *ppv)
{
	OLECHAR* pOleStrRIID = NULL;
	::StringFromCLSID(riid, &pOleStrRIID);

	if ( pOleStrRIID != NULL )
	{
		_bstr_t bstrRIID = pOleStrRIID;

		cout << bstrRIID << endl;

		::CoTaskMemFree(pOleStrRIID);
	}

	if ( ( riid == IID_IHello ) || ( riid == IID_IUnknown ) )
	{
		*ppv = (void *) this;
		AddRef();
	}
	else
		*ppv = NULL;

	return (*ppv == NULL) ? E_NOINTERFACE : S_OK;
}

Re-compile our component.

cl /LD /EHsc HelloComponent.cpp /link /def:HelloComponent.def comsuppw.lib

Now run our “TestApp.exe” application. Once we run it, it will display the below messages:

{00000001-0000-0000-C000-000000000046}
No such interface supported

Find this entry in .h files or search for the name of the interface on the internet. We found it is an IID for IClassFactory. One of the important COM’s common interface IDs.

We will discuss in our next article, the reason behind the CoCreateInterface function to passing internally the IID of the IClassFactory interface.

**

COM – Creating a COM Component using C++ – Inside CoCreateInstance

2 thoughts on “COM – Creating a COM Component using C++ – Inside CoCreateInstance

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top