Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A Friendly Approach to COM Basics

0.00/5 (No votes)
2 Nov 2002 3  
This article will help you to approach COM basics in a friendly manner.

Introduction

This article describes about the simple basics of the ever time evolution in the history of programming, the COM. I think it's useful to the beginners who have no idea about this technology. This is simple and friendly, at least I think...

COM addresses software design in a pragmatic way by designing most commercially proven aspects of classical object orientation.. If you are a developer on Windows then you can't live without knowing what COM is.

The basic COM features

  • COM is a specification. It describes what standards you should follow in order to create a component.
  • COM is object oriented. Each COM object has its own identity and state.
  • COM objects are black boxes.  
  • COM objects can link dynamically. Just visualize them as plug and play devices on your computer: just plug it in and it starts working. Pull it out when you don't need it.
  • COM enables you to create distributed applications too. You don�t even have to know where the COM object resides when you call it. It could even reside somewhere on a remote computer.
  • COM applications can be written in any programming language which supports pointer to a function.
  • COM components are self-versioning. This means that when you upgrade an already existing COM component, it is treated as another version of the same component. This is done because it helps to avoid any version conflicts with older clients.
  • COM components help you implement code reusability. Once a COM component is created, it can be used any number of times in any number of projects as you like.

Types of Components

  • In-process: They are in the form of (DLLs) Dynamic Link Libraries. They run in the memory space of your client application (that's why they are termed as in-process). If they crash, they crash the entire client application with them as they operate in the same memory space as that of the client application.
  • Out-process: They are in the form of (EXEs) Executables. They run in a different memory space as that of your client application (that's why they are termed as out-process). If they crash, it doesn't affect the client application as they operate in a different memory space as that of the client application.
  • Remote: Remote components are just like any other component but the only difference is that remote components run from a separate remote location via a network. They are implemented using DCOM (Distributed COM).

A little about...

COM components have a unique identity number. These numbers are stored in the registry under the HKEY_CLASSES_ROOT main key. COM is, as I explained in its features, not just a specification on paper. It also includes various APIs. It also includes some amount of system-level code. All of this is present in your COM runtime library.

The Component Object Library is itself a system component (which is usually present in your OS) which provides COM components the ability to make calls among different components within a process (in-process), across processes (out-process) or over a network (remote).

Component objects, which you create, are highly encapsulated. When you create a component and distribute it, the client using it can't see the implementation code. He doesn't even have access to the class you have your code in.

As I previously explained, COM objects are black boxes. Although they represent reusable components, reusability is not possible in the fashion of object-oriented languages. COM objects can contain other COM objects and delegate the implementation of specific interfaces to other COM objects. However you cannot derive an object from an existing object in the fashion of deriving a class from a base class in C++.

If this is the case then how does the client use your component to access the services in it? Well, here is where the concept of interfaces jumps in. Every component has an interface, which it has to implement. That interface do not carry any implementations of the methods: those are present in the Co-Class (Component Class). The interface simply contains the method declarations. The interface is the only way a client can access the services of the component.

Now interfaces are implemented using VTables. The VTable contains an array of pointers. These pointers in turn point to the functions of the component. When you create an object of the component in your code, it also creates its VTable in memory.

All COM objects implement a specific interface IUnknown. Through this interface, information about other interfaces a COM object may support can be obtained.

The client creates a pointer to the interface. That pointer points to a virtual pointer. The virtual pointer points to the VTable. Using the interface pointer and the virtual pointer, the client of the component can call any function in it.

There are mainly two types of interfaces:

  • Standard Interfaces: These are the interfaces provided by the COM library. Some of the standard interfaces are IUnknown, IDispatch, IClassFactory, IOle, IDataObject, IStream and IStorage.
  • Custom Interfaces: These are the interfaces created by you.

The Identification of Components

As components are developed and used globally, we have to identify each component uniquely. Now how on earth do you think that this can be done? Well, the Open Software Foundation (OSF) came to the rescue and developed an algorithm that generates a unique identifier called the UUID (Universal Unique Identifier). In COM, it's called the GUID (Global Unique Identifier). The GUID is a number, which is assigned to the interface, class or a library.

COM objects are identified through GUIDs, globally unique interface identifiers. They are 128-byte numbers that are statistically unique; programmers need not worry about anyone else using the same GUID that has been generated through tools or functions provided for this purpose.

We wont get too much into the details of how this algorithm works, but let me tell you the aspects it takes into consideration when it generates that unique identifier:

  • The current date and time
  • The network adapter card address
  • The system clock
  • An automatically incremented counter

Now each COM object has a unique GUID for itself, but where are all of these GUIDs stored? They are stored in your registry. All COM classes are registered in the HKEY_CLASSES_ROOT\CLSID key. For each CLSID key, you also have a sub key called InProcServer32. The value of this sub key will be the filename of the DLL associated with this respective class.

Whenever you create a component, it will be in the form of an EXE or a DLL. You would have to register them on the machine you will be using them on. If you're distributing your component, it could be a part of the installation procedure done automatically, invisible to the user. You could also do the same manually.

A DLL (Dynamic Link Library) can be registered using the following command:

In command line:

REGSVR32 <name of Your COM DLL >

An EXE (Executable) can be registered using the following command:

<COM exe name > /REGSERVER

In this article, I tried to explain the basics and fundamentals of COM to some extent. If you have any suggestions (either positive or negative), please feel free to contact me.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here