COM – Creating a COM Component using C++ – IUnknown interface definition

This is a series of articles explaining creating a COM component using C++. In our previous article, we defined an interface IHello and compiled the IDL file using Microsoft’s MIDL compiler.

Now we are going to define a COM Component using C++. Remember that all the interfaces defined in an IDL file must be implemented.

Step (1). Derive a C++ class from the IHello interface. Add necessary header files.

// HelloComponent.h
//
#include "Hello.h"
#include "Hello_i.c"

class CHelloComponent : public IHello
{
};

Step (2). Declare the class methods in the .h file and implement those methods in the .cpp file for maintainability. Add IHello and IUnknown interface method declarations into CHelloComponent class. IUnknown methods maintain object’s reference counting; to keep object reference count add a variable (eg: m_cRef).

// HelloComponent.h
//
#include "Hello.h"
#include "Hello_i.c"

#include <iostream>

class CHelloComponent : public IHello
{
public:
	CHelloComponent() : m_cRef (1)
	{
	}
	~CHelloComponent()
	{
	}

	// -- IUnknown Methods
	ULONG STDMETHODCALLTYPE AddRef();
	ULONG STDMETHODCALLTYPE Release();
	HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID *ppv);

	// -- IHello Method
	HRESULT STDMETHODCALLTYPE SayHello(BSTR message);

private:
	ULONG m_cRef;
};

Step (3). Let’s implement the IUnknown methods first. AddRef and Release methods of the IUnknown interface maintain the object’s reference counting to ensure the lifetime of the object. Once no references are there for the object; an object will be released from the memory. These things are not done automatically; we need to implement this functionality in AddRef and Release methods. These are the guidelines for the IUnknown interface. Because this is an interface, an implementation doesn’t exist itself. But whoever going to implement the IUnknown interface, should implement these methods.

ULONG CHelloComponent::AddRef()
{
	return (++m_cRef);
}

ULONG CHelloComponent::Release()
{
	if ( --m_cRef != 0 ) 
		return m_cRef; 

	delete this;
	return 0;
}

AddRef will increment and Release will decrement the reference count value by 1. The Release method also releases the object from memory when the reference count is 0. This way we have achieved the initial goal of the IUnknown interface.

Step (4). Another important method of the IUnknown interface is QueryInterface. This method retrieves the requested interface pointer from the callers. A component can implement multiple interfaces. This function should always return the appropriate interface pointer requested by the caller.

HRESULT CHelloComponent::QueryInterface(REFIID riid, LPVOID *ppv)
{
	if ( ( riid == IID_IHello ) || ( riid == IID_IUnknown ) )
	{
		*ppv = (void *) this;
		AddRef(); // -- Maintain the reference count
	}
	else
		*ppv = NULL;

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

In this component, IHello and IUnknown interfaces are implemented. If the requested interface pointer is either of this type, the QueryInterface function will return the pointer to this component. Otherwise, this returns, a NULL pointer with E_NOINTERFACE return code.

Step (5). Now we have to implement IHello‘s SayHello method. This method simply takes a string as an argument and displays the string on the console window.

HRESULT CHelloComponent::SayHello(BSTR message)
{
	_bstr_t bstrMessage = message;

	cout << bstrMessage << endl;

	return S_OK;
}

_bstr_t class is the helper class that deals with BSTR data types. It internally maintains resource allocation and deallocation for BSTR data types or you can specify it through its parameter.

Step (6). Include the necessary files in HelloComponent.cpp file.

#include "HelloComponent.h"

// -- for _bstr_t
#include <comutil.h>

// -- for std namespace; for cout etc.,
using namespace std;

Step (7). Now compile HelloComponent.cpp from the command prompt using Microsoft’s tool cl.exe.

cl HelloComponent.cpp /EHsc /c

The file HelloComponent.cpp will compile and it will generate a .obj file.

Now the HelloComponent is ready. But, this is not enough to deploy the component. We need to wrap the component into a DLL and register it into the Windows registry to complete the deployment. We will discuss these in our next articles.

**

COM – Creating a COM Component using C++ – IUnknown interface definition

One thought on “COM – Creating a COM Component using C++ – IUnknown interface definition

Leave a Reply

Your email address will not be published.

Scroll to top