This article provides a very brief introduction to COM and ATL. For more information on COM, see "The Component Object Model" in the Win32 SDK. For more information on ATL, see the ATL Article Overview and the ATL Class Overview.
COM is the fundamental object model on which ActiveX and OLE are built. COM allows an object to expose its functionality to other components and to host applications. It defines both how the object exposes itself and how this exposure works across processes and across networks. COM also defines the object's life cycle.
Fundamental to COM are these concepts:
See Also "The Component Object Model" in the Win32 SDK
An interface is the way in which an object exposes its functionality to the outside world. In COM, an interface is a table of pointers (like a C++ vtable) to functions implemented by the object. The table represents the interface, and the functions to which it points are the methods of that interface. An object can expose as many interfaces as it chooses.
Each interface is based on the fundamental COM interface, IUnknown. The methods of IUnknown allow navigation to other interfaces exposed by the object.
Also, each interface is given a unique interface ID (IID). This uniqueness makes it is easy to support interface versioning. A new version of an interface is simply a new interface, with a new IID.
Note IIDs for the standard COM, OLE, and ActiveX interfaces are pre-defined.
See Also "COM Objects and Interfaces" in the Win32 SDK
Back to Introduction to COM | Back to Top
IUnknown is the base interface of every other COM interface. IUnknown defines three methods: QueryInterface, AddRef, and Release. QueryInterface allows an interface user to ask the object for a pointer to another of its interfaces. AddRef) and Release implement reference counting on the interface.
See Also "IUnknown and Interface Definition Inheritance" in the Win32 SDK
Back to Introduction to COM | Back to Top
COM itself does not automatically try to remove an object from memory when it thinks the object is no longer being used. Instead, the object programmer must remove the unused object. The programmer determines whether an object can be removed based on a reference count.
COM uses the IUnknown methods, AddRef and Release, to manage the reference count of interfaces on an object. The general rules for calling these methods are:
In a simple implementation, each AddRef call increments and each Release call decrements a counter variable inside the object. When the count returns to zero, the interface no longer has any users and is free to remove itself from memory.
Reference counting can also be implemented so that each reference to the object (not to an individual interface) is counted. In this case, each AddRef and Release call delegates to a central implementation on the object, and Release frees the entire object when its reference count reaches zero.
See Also "Managing Object Lifetimes through Reference Counting" in the Win32 SDK
Back to Introduction to COM | Back to Top
Although there are mechanisms by which an object can express the functionality it provides statically (before it is instantiated), the fundamental COM mechanism is to use the IUnknown method called QueryInterface.
Every interface is derived from IUnknown, so every interface has an implementation of QueryInterface. Regardless of implementation, this method queries an object using the IID of the interface to which the caller wants a pointer. If the object supports that interface, QueryInterface retrieves a pointer to the interface, while also calling AddRef. Otherwise, it returns the E_NOINTERFACE error code.
See Also "QueryInterface: Navigating in an Object" in the Win32 SDK
Back to Introduction to COM | Back to Top
The COM technique of marshaling allows interfaces exposed by an object in one process to be used in another process. In marshaling, COM provides code (or uses code provided by the interface implementor) both to pack a method's parameters into a format that can be moved across processes (as well as, across the wire to processes running on other machines) and to unpack those parameters at the other end. Likewise, COM must perform these same steps on the return from the call.
Note Marshaling is typically not necessary when an interface provided by an object is being used in the same process as the object. However, marshaling may be needed between threads.
See Also "Marshaling Details" in the Win32 SDK
Back to Introduction to COM | Back to Top
There are times when an object's implementor would like to take advantage of the services offered by another, pre-built object. Furthermore, it would like this second object to appear as a natural part of the first. COM achieves both of these goals through containment and aggregation.
Aggregation means that the containing (outer) object creates the contained (inner) object as part of its creation process and the interfaces of the inner object are exposed by the outer. An object allows itself to be aggregatable or not. If it is, then it must follow certain rules for aggregation to work properly.
Primarily, all IUnknown method calls on the contained object must delegate to the containing object.
See Also "Reusing Objects" in the Win32 SDK
Back to Introduction to COM | Back to Top
ATL is the Active Template Library, a set of template-based C++ classes with which you can easily create small, fast Component Object Model (COM) objects. It has special support for key COM features including: stock implementations of IUnknown, IClassFactory, IClassFactory2 and IDispatch; dual interfaces; standard COM enumerator interfaces; connection points; tear-off interfaces; and ActiveX controls.
ATL code can be used to create single-threaded objects, apartment-model objects, free-threaded model objects, or both free-threaded and apartment-model objects.
Topics covered in this section include:
A template is somewhat like a macro. As with a macro, invoking a template causes it to expand (with appropriate parameter substitution) to code you have written. However, a template goes further than this to allow the creation of new classes based on types that you pass as parameters. These new classes implement type-safe ways of performing the operation expressed in your template code.
Template libraries such as ATL differ from traditional C++ class libraries in that they are typically supplied only as source code (or as source code with a little, supporting run time) and are not inherently or necessarily hierarchical in nature. Rather than deriving from a class to get the functionality you desire, you instantiate a class from a template.
Back to Introduction to ATL | Back to Top
ATL allows you to easily create COM objects, Automation server, and ActiveX controls. ATL provides built-in support for many of the fundamental COM interfaces.
ATL is shipped as source code which you include in your application. ATL also makes a DLL available (atl.dll), which contains code that may be shared across components. However, this DLL is not necessary.
See Also Creating an ATL Project
Back to Introduction to ATL | Back to Top
When developing components and applications, you can choose between two approachesATL and MFC (the Microsoft Foundation Class Library).
Using ATL
ATL is a fast, easy way to both create a COM component in C++ and maintain a small footprint. Use ATL to create a control if you don't need all of the built-in functionality that MFC automatically provides.
Using MFC
MFC allows you to create full applications, ActiveX controls, and active documents. If you have already created a control with MFC, you may want to continue development in MFC. When creating a new control, consider using ATL if you don't need all of MFC's built-in functionality.