| Lesson 2 | Prerequisites |
| Objective | Understand the prerequisite COM and C++ knowledge required for this course. |
Microsoft COM Reuse Mechanisms enable components to leverage existing functionality without duplicating code, promoting modularity and interoperability in Windows-based software. The two primary techniques are containment/delegation and aggregation. Both allow one COM component to build on another at the binary level, without requiring access to the inner component's source code, across process boundaries, language boundaries, and compiler boundaries.
In containment and delegation, the outer component holds the inner component as a private member object. The outer component creates the inner object, controls its lifetime, and forwards selected interface calls to it. The outer component determines which of the inner object's capabilities are exposed to clients and which are hidden. This is the simpler of the two techniques because the outer component's identity is always maintained: clients always interact with the outer object's own IUnknown.
In aggregation, the outer component exposes the inner component's interfaces directly to clients as if they were the outer component's own interfaces. The inner object's IUnknown pointer is handed directly to clients. This requires strict IUnknown pointer exchange rules to be observed. The inner object's constructor must receive the outer object's IUnknown, known as the controlling unknown, as a parameter. The inner object must delegate its QueryInterface, AddRef, and Release calls to the controlling unknown when it is being aggregated. Failure to implement these rules correctly results in circular reference counting, identity violations, and memory leaks that are difficult to diagnose at runtime.
Both containment and aggregation support binary-level reuse, forming a cornerstone of COM's design for building complex, extensible applications from reusable binary components.
Advanced COM (COM Fundamentals II) builds on the information presented in COM Fundamentals I (Basic COM). Before beginning this course, you should have a working knowledge of the following topics from COM Fundamentals I:
IUnknown interface navigation, IUnknown reference counting,
IClassFactory, interface definition language (IDL), the Microsoft IDL
(MIDL) compiler, and the Active Template Library (ATL)COM Fundamentals II is intended for professional C++ developers building software components using Microsoft's Component Object Model. Much of the course builds directly on C++ language features. To get the most from this course, you should have a solid understanding of the following C++ concepts:
You do not need to be an expert in every area, but you should understand what each concept means and have used it in practice. You should have experience developing COM objects in in-process servers using ATL, and you should understand how ATL supports COM objects via multiple inheritance.
For tooling, this course assumes you are working with Visual Studio 2022 with the Desktop development with C++ workload installed, or Visual Studio Code with the MSVC compiler toolchain. The ATL COM wizard in Visual Studio 2022 generates COM object scaffolding, IDL files, and registration code and remains the standard starting point for COM server development in modern Windows environments.
The Component Object Model (COM) is an application programming interface (API) that defines how software objects are created, identified, and connected to one another at the binary level. A COM object is a software construct that provides services to a client. The client may be another COM object, a conventional application, or any other piece of software that knows how to use a COM interface. COM objects are packaged in components: binary files stored on disk, either as DLLs (in-process servers) or EXEs (out-of-process servers).
What distinguishes COM from earlier reuse mechanisms such as static libraries, class libraries, and dynamic link libraries is the level at which its contracts are defined. Traditional libraries define their contracts at the source code level or at the level of a specific compiler's name mangling and calling conventions. This means that reusing a library typically requires the same language, the same compiler, or at minimum the same platform ABI. COM defines its contracts at the binary vtable level. The interface contract specifies exactly how a pointer to an interface is laid out in memory and how methods are called through that pointer. Any language or compiler that can produce code conforming to that binary layout can implement or consume a COM interface.
COM is therefore not a language and not a framework. It is a binary specification. It does not define how a component is built internally. It defines only how a client connects to a COM object and how that object responds. This separation of interface from implementation is what makes COM language-independent in practice and what allows COM objects written in C++, Visual Basic, Delphi, and other languages to interoperate without modification.
Understanding COM's place in the evolution of Windows development technology provides context for why the concepts covered in this course remain relevant.
COM was introduced by Microsoft in 1993 as the binary interface standard for component software on Windows. It established the vtable-based interface model, the IUnknown contract, reference counting for lifetime management, and the registry-based activation model using CLSIDs and ProgIDs.
COM+ was introduced with Windows 2000 as a transactional extension to COM built on the Microsoft Transaction Server (MTS) infrastructure. COM+ added object pooling, queued components, role-based security, and the COM+ Catalog as a replacement for direct registry-based component configuration. COM+ is still actively used in enterprise Windows applications that require distributed transaction support.
Distributed COM (DCOM) extends the COM binary model across network boundaries. DCOM allows a COM client to call a COM server running on a remote machine transparently, using RPC as the transport. DCOM was the predecessor to .NET Remoting and Windows Communication Foundation (WCF) for distributed Windows application development and remains in use in legacy enterprise systems.
The .NET Common Language Runtime, introduced in 2002, provides COM interoperability through two wrapper mechanisms. The Runtime Callable Wrapper (RCW) allows managed .NET code to consume COM objects: the RCW handles reference counting, marshalling, and lifetime management on behalf of the .NET client. The COM Callable Wrapper (CCW) exposes a .NET object as a COM server to unmanaged COM clients. These wrappers allow COM and .NET components to coexist in the same process without requiring either side to be rewritten.
WinRT, the Windows Runtime introduced with Windows 8 in 2012, is built on a COM-derived binary interface model. WinRT interfaces use ABI-level COM conventions: IInspectable extends IUnknown, adding reflection and activation capabilities. Developers with COM knowledge can read WinRT ABI headers, implement WinRT interfaces in C++, and understand the lifetime and identity rules that govern WinRT objects. WinRT is used by the Universal Windows Platform and by modern Windows APIs including DirectX 12 and Windows ML.
COM remains actively used in the following areas of modern Windows development:
The concepts covered in COM Fundamentals II apply directly to all of these contexts. Understanding containment, aggregation, IUnknown identity, ATL server implementation, and binary interface design provides the foundation for working with any COM-based API on Windows, including WinRT at the ABI level.