COM: Creating a COM Component using C++ (Part-8)

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

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

  • It actually internally calls another function CoGetClassObject
  • CoGetClassObject checks the registry entires for CLSID which was passed through our CoCreateInstance function.
  • If CoGetClassObject finds the location of the DLL associated with the CLSID, it calls 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 COM library expected.

But why our client application is failing to create an instance of our HelloComponent class? Lets re-check the error our test application is displaying. Our test application is displaying “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 component. 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 DllGetClassObject function directly, without calling CoCreateInstance. It seems our CoCreateInstance function is playing something tricky here which is what we aren’t expected. 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 E_NOINTERFACE error.

Then we need to figure it 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 for this entry in .h files or search for the name of the interface on internet. We found it is an IID for IClassFactory. One of the important COM’s common interface ID.

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

**

1 comment for “COM: Creating a COM Component using C++ (Part-8)

Leave a Reply