A Review of COM
Servers
After you create one or more COM classes, you need
to package the classes and install them on a system. The package is
called a COM Server, which is a
dynamically activated collection of the implementations of one or
more COM classes. Modern Win32 versions of COM enable you to create
a COM server as an in-process (inproc) server (a dynamic link
library), an out-of-process server (an executable), or, on the
Windows NT/2000/XP/2003 operating system, a system service
executable.
A COM server has three jobs, in addition to
hosting the implementations of its classes:
-
Register and unregister all classes in the
server and, potentially, the server itself.
-
Provide the COM Service Control Manager (SCM)
access to all COM class objects
implemented by the server (often called exposing the class objects). Class objects are
frequently called class factory
objects because they generally implement the
IClassFactory interface.
-
Manage the server's lifetime. This typically
means allowing the SCM to unload an inproc server from memory when
it's no longer used. A local server often terminates when there are
no more references to objects managed by the server.
Technically, the first and third items are
optional, but all COM servers should implement this functionality.
Exactly how a server does this depends on the type of server.
Inproc
Servers
An
inproc server is a dynamic link library (DLL) that contains five
well-known entry points, one for the Win32 operating systems and
the other four for COM:
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason,
LPVOID lpReserved);
STDAPI DllRegisterServer(void);
STDAPI DllUnregisterServer(void);
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid,
LPVOID* ppv);
STDAPI DllCanUnloadNow(void);
Each of the Win32 operating systems calls a
DLL's DllMain function when it loads a DLL into a process
and removes a DLL from a process. The operating system also calls
DllMain each time the current process creates a new thread
and when a thread terminates cleanly. This function is optional but
present in all ATL inproc servers.
The DllRegisterServer and
DllUnregisterServer functions create and remove,
respectively, in the Windows Registry all entries necessary for the
correct operation of the server and its classes. When you use the
REGSVR32 utility to register or unregister an inproc server, the
utility loads the DLL and calls the appropriate one of these
function in the DLL. Technically, both of these functions are
optional, but, in practice, you want to have them in your
server.
The COM SCM calls a server's
DllGetClassObject function when it requires a class object
exposed by the server. The server should return the requested
interface, riid, on the specified class object,
rclsid.
When you call the CoFreeUnusedLibraries
API, COM asks each inproc server in your process whether COM should
unload the DLL by calling the DllCanUnloadNow function. An
S_OK return value means that the server permits COM to
unload the server. An S_FALSE return value indicates that
the server is busy and COM cannot unload it.
Local Servers and
Service-Based Servers
A local server or Windows service is an
executable image (EXE) server that contains one well-known entry
point:
extern "C"
int WINAPI _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd);
Executables cannot provide multiple specialized
entry points as DLLs can, so a local server must use a different
technique to implement the three requirements of a COM server:
registration, exposed class objects, and lifetime management.
A local server registers and unregisters itself,
and then immediately terminates when the server parses its command
line and finds the well-known (noncase-sensitive) command-line
switches Regserver and UnregServer,
respectively.
A local server exposes its class objects by
calling the CoRegisterClassObject API and handing an
IUnknown interface pointer to each of the server's class
objects to the SCM. A local server must call this API after the SCM
starts the server process. When the server is ready to
shut down, it must first call CoRevokeClassObject to
notify the SCM that each of the server's class objects is no longer
available for use.
A local server manages its own lifetime. When a
server detects that there are no references to any of the objects
managed by the server, the server can shut downor not, as desired.
As you'll see later in this chapter, detecting that there are no
references is a little trickier than you might think.
COM Createable and
Noncreateable Classes
A COM createable
class is a COM object class that supports using the
CoCreateInstance API to create instances. This implies
that the class must provide a class object and that the class
object implements the IClassFactory interface.
A noncreateable class typically provides no
class object, so calling CoCreateInstance using the
class's CLSID fails. In many designs, far more noncreateable
classes exist than createable ones. For example, one version of
Microsoft Excel had approximately 130 classes, only 3 of which were
createable. You typically access interfaces on noncreateable
classes through properties or methods on createable classes or on
classes that have already been created by other means.
|