COM is a binary standard for Windows objects. That means that objects can execute the executable code (in a DLL or EXE) that describes another object. Even if two objects were written in different languages, they can interact using the COM standard.
How do they interact? Through an interface . A COM interface is a collection of functions, or really just function names . It's a C++ class with no data, only pure virtual functions. Your objects provide code for the functions. Other programs get to your code by calling these functions. All COM objects must have an interface named IUnknown (and most have many more, all with names that start with I , the prefix for interfaces).
The IUnknown interface has only one purpose: finding other interfaces. It has a function called QueryInterface() that takes an interface ID and returns a pointer to that interface for this object. All the other interfaces inherit from IUnknown , so they have a QueryInterface() too, and you have to write the codeor you would if there was no ATL. Three functions are declared in IUnknown: QueryInterface() , AddRef() , and Release() . The latter two functions keep track of which applications are using an interface. All interfaces inherit all three functions and the developer of the interface must implement them.
COM provides services to programmers. For example, you don't need to locate a component to execute a function within it. If the component is properly registered, COM can find it and load it for you. COM also handles any marshaling or other preparation that is required for you to call a COM component's functions. (If the component is in-process, as an ActiveX control is, the client speaks directly to the component without having to go through the runtime.)
Applications and libraries that run in the .NET runtime also provide binary compatibility, marshaling, and component discovery and loading. In fact, the .NET runtime is a replacement for COM. As you'll see in this chapter, new managed code (in any language) can call unmanaged code if that unmanaged code defines a COM component. What's more, unmanaged code can call into managed code by treating the .NET component as though it were a COM component. However, this interoperability has a small performance penalty, so you might choose to do new development as a COM component to speed access to that component from unmanaged code, while still permitting access from managed code.