| OHSWG | 1997.12.15 |

Open Hypermedia Systems Working Group
DCOM
The Distributed Component Object Model (DCOM) is the product (and vision) of Microsoft Corporation, the architecture to take their operating systems (Win95 and NT) forward into the next decade. There is much confusion about where COM and DCOM fit into the Microsoft model, particularly the relationship with OLE and ActiveX. Before anything else I shall try to clarify these relationships. Microsoft's OLE (1.0 the original incarnation) was Object Linking and Embedding. This is the now familiar process of embedding data from one program within another, while using the original to edit that data. It was based on DDE (Dynamic Data Exchange). OLE 2.0 and later OLE pronounced O'lay) are the more recent versions of OLE 1.0, they are based on COM technologies and allow (among other things) automation. ActiveX controls are COM objects that represent an individual control on the screen, like a Java Bean. COM itself has become an important technology in its own right and the whole lot is labeled under the banner of ActiveX (!)
So COM is the underlying architecture of OLE, ActiveX controls and Automation. It was developed with these things firmly in mind :
Thus COM is an architecture and supporting infrastructure for building, using and evolving component software in a robust manner. DCOM is the distributed version, where components can be located on a separate machine. The location of the objects are transparent to the programmer who can use the same code to use local or distributed COM objects. All the work is done by the OLE library on each machine.
COM defines a standard way to lay out virtual function tables (vtables) in memory, and a standard way to call functions through those vtables. Thus any programming language that can access functions through pointers (C, C++, Smalltalk, Ada, and BASIC) can be adapted to use a COM object.

This architecture means that, on a local machine, each function call only has to be redirected twice. Performance was of paramount importance when designing COM and the whole function call procedure gives performance similar to traditional C++ object method calls.
COM objects expose methods via interfaces. Unlike CORBA a COM component can expose multiple interfaces. An interface is best described as a contract between the COM object and controlling software, such that the COM object will always support the methods described in the interface. Those methods never change. Alterations occur to a COM object by adding and removing interfaces, not by changing the methods they reveal. By allowing applications to dynamically query for interfaces the versioning problems commonly associated with Dynamic Link Libraries are avoided. If the COM Object supports the interface then it is returned by the query mechanism and behaves as expected, else the query is denied and the application can behave sensibly.
This querying is controlled by an interface that all other COM interfaces must derive from, IUnknown. IUnknown supports three methods; Addref, Release and QueryInterface. QueryInterface implements the dynamic query mechanism described above, while Addref and Release implement the reference counting that controls the lifetime of any COM object. When an object's internal reference count reaches zero, then that object is free to unload itself.
Each Component is identified with a CSLID, this is a GUID, a 128-bit integer that can be generated with a variety of tools (including 'uuidgen', distributed by Microsoft with it's developer products). Each interface also has a unique GUID, known as a IUID. Thus to use a particular interface the programmer has to do the following tasks:
The COM Library is the system component that handles all the COM calls within the OS. When an application creates a COM component, it passes the CLSID of that COM component class to the COM Library. The COM Library uses that CLSID to look up the associated server code in the registration database. If the component is implemented as an executable, when it is launched the server code uses the IClassFactory interface to register itself. If that code is within a DLL, COM loads the DLL and registers the component itself. If the server code is on a separate machine then the Library contacts that machine and requests a reference to the required object. The COM Library on that machine handles all the remote invocation requests.
The server code must have implemented the IClassFactory interface. This interface (and the more security heavy IClassFactory2) generate the actual instances of the components held within that executable.
COM is designed to let applications access components regardless of where they are running. In or out of process or on a separate machine. From a client's point of view, all COM components are accessed through interface pointers which are in-process. If the COM component is in-process, the call reaches it directly. If the COM component is out-of-process, the call first reaches what is called a proxy object provided by COM that generates the appropriate remote procedure call to the other process or the other machine.
From a server's point of view, all calls to a COM component's interface functions are made through a pointer to that interface, again in process. If the COM component is in-process, the caller is the client itself. Otherwise, the caller is a stub object provided by COM that picks up the remote procedure call from the proxy in the client process and turns it into an interface call to the server COM component. Thus as far as both clients and servers know, they always communicate directly with some other in-process code.

When a developer is defining a new Interface they use a variation of IDL. This IDL can then be run through an appropriate IDL compiler to create header files and source code for proxy and stub objects that handle the remote calls. An example IDL file for an ICount interface is given in the Example section. Microsoft already provides a wide variety of COM objects that can be used within Windows. These include utility functions as well as those for manipulating OLE and Automation.
COM objects are not Classical object, neither are the interfaces that they support. One noticeable difference between COM and Classical objects is that interfaces for COM objects do not support multiple inheritance and the inheritance they support does not mean code inheritance, merely the specification of the interface itself. The COM objects themselves, the components, do not support inheritance at all. Micosoft argues that inheritance violates the principle of encapsulation, the most important aspect of an object-oriented system. Being inherited from another class means that you must know the internal workings of that class. So with COM two methods are used to get the same effect while retaining the independence of one COM object from another.
Another important point to make is that COM objects exist to expose methods to the client. In this case it is unimportant which instance of an object is referenced by a client as both objects will expose the same methods. This inability to get a reference to a particular object instance would cause a serious problem with some distributed systems. Microsoft have introduced Monikers to bypass this problem.
Monikers are objects that implement the IMoniker interface, and are generally implemented in DLLs as component objects. There are two ways of viewing the use of monikers: as a moniker client, a component that uses a moniker to get a pointer to another object, and as a moniker provider, a component that supplies monikers identifying its objects to moniker clients. A Moniker can be attached to another COM object (a process known as binding) and then be used to obtain that specific object.
Using these concepts COM maintains a black-box ideology, while supporting the traditional object notions of encapsulation, polymorphism, and reusability.
| Start Page | Description | Example | Availability | Recommendations | References |
David Millard