COM: The Component Object Model

Component-based software development is big business. Instead of writing one deeply intertwined piece of software (called monolithic software development), a team writes a set of many smaller components that talk to one another. This ends up being an advantage because if the components are modular enough, they can be used in other projects without a lot of headache. Not only that, but the components can be updated and improved independently of each other. As long as the components talk to each other the same way, no problems arise.
To aid in component-based software design, Microsoft created a scheme called the Component Object Model, or COM for short. It provides a standard way for objects to communicate with other objects and expose their functionality to other objects that seek it. It is language independent, platform independent, and even machine independent (a COM object can talk to another COM object over a network connection). In this section we cover how COM objects are used in component-based software. As the knowledge required to construct your own COM objects is not necessary for this book, you may want to look in some other books devoted to COM if you need more information.
A COM object is basically a block of code that implements one or more COM interfaces. (I love circular definitions like this. Look up "worrier" in the dictionary; it's defined as "someone who worries.") A COM interface is just a set of functions. Actually, it's implemented the same way that almost all C++ compilers implement virtual function tables. In C++, COM objects just inherit one or more abstract base classes, which are called COM interfaces. Other classes can get a COM object to do work by calling functions in its interfaces, but that's it. There are no other functions besides the ones in the interfaces, and no access to member variables outside of Get/Set functions existing in the interfaces.
All COM interfaces derive, either directly or indirectly, from a class called IUnknown. In technical terms, this means the first three entries in the vTable of all COM interfaces are the same three functions of IUnknown. The interface is provided in the following:
   typedef struct interface   interface IUnknown   {       virtual HRESULT QueryInterface( REFIID idd, void** ppvObject) = 0;       virtual ULONG AddRef( void)= 0;       virtual ULONG Release( void) = 0;   };
AddRef and Release implement reference counting for us. COM objects are created outside of your control. They may be created with new, malloc, or a completely different memory manager. Because of this you can't simply delete the interface when you're done with it. Reference counting lets the object perform its own memory management. The reference count is the number of other pieces of code that are referencing an object. When you create a COM object, the reference count will most likely be 1, since you're the only one using it. When another piece of code in a different component wants an interface, generally you call AddRef() on the interface to tell the COM object that there is an additional piece of code using it. When a piece of code is done with an interface, it calls Release(), which decrements the reference count. When the reference count reaches 0, it means that no objects are referencing the COM object and it can safely destroy itself.
Warning If you don't release your COM objects when you're done with them, they won't destroy themselves. This can cause annoying resource leaks in your application.
QueryInterface is the one function that makes COM work. It allows an object to request another interface from a COM object it has an interface for. You pass QueryInterface an interface ID, and a pointer to a void pointer to fill with an interface pointer if the requested interface is supported.
As an example, let's consider a car. You create the car object and get an interface pointer to an iCarIgnition interface. If you want to change the radio station, you can ask the owner of the iCarIgnition interface if it also supports the iCarRadio interface.

Post a comment