Clients need a mechanism for finding class objects. Because of the dynamic nature of COM, this may involve loading a DLL or starting a server process. This act of bringing an object to life is called object activation.
COM has three activation models that can be used to bring objects into memory to allow method calls to be invoked. Clients can ask COM to bind to the class object of a given class. Clients can also ask COM to create new instances of a class based on a CLSID. Finally, clients can ask COM to bring a persistent object to life based on the persistent state of the object. Of these three models, only the first model (binding to a class object) is absolutely necessary. The other two models are simply optimizations of commonly used activation idioms. Additional user-defined activation models can be implemented in terms of one (or more) of these three primitives.
Figure 3.1 The COM Library and SCM
Each of COM’s three activation models uses the services of the COM Service Control Manager or SCM.2 The SCM is the central rendezvous point for all activation requests on a particular machine. Each host machine that supports COM has its own local SCM that forwards remote activation requests to the SCM on the remote machine, where the activation request will be treated as a local activation request. The SCM is used only to activate the object and bind the initial interface pointer. Once the object is activated, the SCM is not involved with client-object method invocation. As shown in Figure 3.1, under Windows NT the SCM is implemented in the RPCSS Service. The services of the SCM are exposed to programs as high-level moniker types3 and as low-level API functions, all of which are implemented in what the Component Object Model Specification calls the COM library. Under Windows NT, the majority of the COM library is implemented in OLE32.DLL. For efficiency, the COM library can use local or cached state to avoid making unnecessary interprocess communication (IPC) requests to the RPCSS service.
Recall that the first principle of COM is the separation of interface from implementation. One implementation detail that is hidden from the client is where an object implementation resides. Not only is it impossible to detect generically which host machine an object is activated at, it is also impossible to detect whether a local object was activated in the client’s process or in a distinct process on the local machine. This gives object implementors a great deal of flexibility in terms of deciding how and where to deploy object implementations, taking into account issues such as robustness, security, load balancing, and performance. The client does get an opportunity at activation time to indicate a preference as to where an object will be activated; however, many clients indicate that they don’t care, in which case the SCM will decide based on the current configuration of the desired class.
When an object is activated in process, the DLL that implements the object’s methods is loaded into the client process and all of the object’s data members reside in the client’s address space. This makes method invocation extremely efficient, as no process-switch is required. In addition, the client’s thread can be used to execute the method code directly, provided the object’s threading requirements match those of the client. If the client and the object have compatible threading requirements, then no thread-switch is required either. When method calls can execute using the client’s thread, no intermediate runtime is involved after the object is activated and the method invocation cost is simply that of making a virtual function call. This makes in-process COM especially well suited for performance-sensitive applications, as method invocation is no more expensive than a normal global function call into a DLL.4
When an object is activated out of process (i.e., in a different process on the local or remote machine), the code that implements the object’s methods executes in a distinct server process and all of the object’s data members reside in the server process’s address space. To allow the client to communicate with the out-of-process object, COM transparently returns a proxy to the client at activation-time. As is discussed in detail in Chapter 5, this proxy runs on the client’s thread and translates method invocations into RPC requests to the server’s execution context, where these RPC requests are then translated back into method invocations on the actual object. This makes method invocation less efficient, as a thread-switch and process-switch are required for each access to the object. The benefits of out-of-process activation include fault isolation, distribution, and increased security. Chapter 6 will discuss out-of-process activation in detail.
2 Windows NT also has a subsystem known as the Service Control Manager that is used to start logon-independent processes known as Services. For the remainder of this book, the Windows NT Service Control Manager will be referred to as the NT SCM to distinguish it from the COM SCM.
3 Monikers are locator objects that hide the details of an activation or binding algorithm. Monikers are discussed in greater detail later in this chapter.
4 The level of indirection needed to call into an external DLL is roughly equivalent to that of calling a function through a vtbl entry.