Advertising

COM

Contents

Component Object Model

COM is Microsoft's 'binary object interoperability standard'. Such standards allow us to build separate program components which can work together.

Within an application we use objects to aid development but ultimately all those objects are contained within one block of code. If we want to reuse any part of the application in another project we need access to the source code of the particular class. Note that this also leads to duplication of code: Source code is being reused, but executable code is being duplicated.

COM classes, however, are available to the whole system at run-time and can be used without access to the source code. The individual components in a solution can be replaced with improved implementations without having to recompile the whole solution.

Note that COM objects are not true Object-Orientated objects because Inheritance can not be used at the COM level.

Because the user of a COM class doesn't require its source code, an application can use various COM classes which may have been written in various languages.

In theory COM is a cross-platform technology, but the non-Windows implementations are pure vapourware. Also, COM objects, can in theory, be built using any language, but it's easier in an Object-Orientated language. For instance, we can make a COM class by building the appropriate C++ or Java class. Though we can expect some level of Java implementation, COM seems certain to remain tied to Windows and Visual C++.

How COM works.

COM must be an additional part of the Operating System.

The OS maintains a registry of all available classes and helps COM objects talk to each other.

This generally consists of:

Each COM class exposes some methods and properties, like a C++ class. There are some standard methods and properties which another COM object might expect (especially when dealing with User Interface classes), but each COM object really needs to be supplied with documentation if it is to be used by strangers.

Each COM class has a type library (sometimes in a separate file) which describes its methods and properties. This type library provides a unique code for the COM class (CLSID) and unique codes for each method (UUID). These codes are used by the background COM system instead of the class and method names to reduce conflicts.

The COM layer on top of C++.

COM classes implement various Interfaces. Interfaces are just sets of methods which a class should implement. Every COM class implements an interface called IUnknown.

An interface contains pointers to the actual methods of the interface, so a pointer to the interface can provide pointers to all its methods.

COM Interface methods return data through their arguments. Their return type is HRESULT, used to indicate success or an error code.

An Interface should be regarded as a binding contract. After the first version of the COM class has been released the names of the methods may not be changed and new methods may not be added. However, new Interfaces may be added and an existing Interface may be superseded. For instance IExample may be superseded with IExample2. Programmers may choose to use this new interface but the older interface will always be available as well.

IUnknown

All COM classes implement the IUnknown interface, which consists of the following methods:

HRESULT QueryInterface()
ULONG AddRef()
ULONG Release()

Note that AddRef and Release are the only COM methods which do not return HRESULT.

QueryInterface() is used to check whether the class implements a particular Interface. It is passed an Interface ID and a pointer for return. It evaluates to E_NOINTERFACE if the Interface is not supported. It is used by Windows to check for various standard interfaces.

AddRef() and Release() are used to increment and decrement an internal counter. When that counter is zero, the COM systems knows that it may remove the COM object from memory.

All other Interfaces support IUnknown so a pointer to any other Interface is a pointer to an IUnknown, which in turn means that a pointer to any Interface can be used to retrieve the pointer to any other Interface which the COM class implements.

Whenever QueryInterface is used to request a pointer to IUnknown it must return the same IUnknown. This can be used to check how many unique objects are being dealt with.

Creating Instances

CoCreateInstance() is a Windows API call which can be used to create an instance of a COM class. It is passed a CLSID for the COM class.

Each COM class has an associated Class Factory, which is used by the COM system to create instances of the COM class. The Class Factory is controlled through its IClassFactory Interface.

CoCreateInstance uses this Class Factory to create an instance and returns a pointer to the IUnknown of the instance.

Types of COM class

COM classes may be one of three types of server:

Early Binding / Late Binding

When using Early Binding the compiler figures out the pointer to the method at compile-time. This direct approach offers best performance.

Late Binding involves querying the COM object for the method pointer before using it. Late Binding is used by Visual Basic and Automation because they must be able to deal with COM classes they have never seen before. Interpreted environments such as Visual Basic often switch to using Early Binding when the application is compiled. Late Binding uses the IDispatch Interface.

IDispatch

If a COM class can be accessed by Late Binding then it will implement IDispatch and each of its methods will have a unique DispID.

IDispatch::Invoke() is passed a DispID and any necessary arguments. It then calls the requested method with these arguments.

IDispatch::GetIDsOfNames can be used to get the DispIDs of the methods and properties.

Obviously because this additional layer is involved in every method call between the COM clients performance is significantly lower than when using Early Binding.

Visual C++ makes it relatively simple to implement both Early Binding and Late Binding. Therefore today's COM classes are expected to do so. 

Copyright © Murray Cumming. Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved.

Murray's Web Pages