General Notes
DllRegisterServer
DllUnregisterServer
LoadLibrary
and get a pointer to the DllRegisterServer
function using the GetProcAddress
API call. It will then just call this function. This process can also be done by using the program supplied by Microsoft called "regsvr32.exe". For eg.,
c:\>regsvr32 Server.dll
IClassFactory
. This interface has a method called CreateInstance
which knows how to create the component that implements a certain interface. The next obvious questions is - "How do we get to this component?".
DllGetClassObject
in your server. It then calls this function passing in the name (the CLSID
) of the class factory that it is looking for. The server returns a reference to the component. Simple.CoRegisterClassObject
for each class object.
This is done so that subsequent requests from the clients for the same component can be resolved to this already executing process instead of creating a new one (but it is to be noted that it is also possible to specify that a new process will be executed for every instance of the component).
Shutting Down
This process again, differs in the case of inproc and outproc servers.
DllCanUnloadNow
in your DLL. You can reply affirmatively (by returning S_OK
) if you determine that nobody is using your comonent or refuse (by returning S_FALSE
) for any other reason.
This unregistration is performed by calling CoRevokeClassObject
.
Server Locks
The standard component creation interface that must be implemented by all components is IClassFactory
. Typically, the object reference handed out by DllGetClassObject
in case of inproc servers and the class object registered with COM by calling CoRegisterClassObject
in case of outprocess servers will be a component that implements IClassFactory
(but it need not be so).
This interface has only 2 methods,
CreateInstance
LockServer
CreateInstance
method, well, creates the component.
Every component server (whether inproc or outproc) must maintain, a count of the number of active objects in the server in order to determine when to shutdown. This is typically done by maintaining a reference count that is bumped up when an object instance is created (either in the class factory's CreateInstance
method or in the component's AddRef
method the first time it is called) and bumped down when an object instance is deleted (in the component's Release
method just before the object is physically deleted). When this reference count becomes zero, it is safe to unload the server.
Now, it is possible that a certain client may periodically create a component, use its services and then release it. If this is the only client for that component, then everytime the client creates an instance of it, the server must be loaded into memory (or spawned) and everytime the client releases its reference to it, it must be unloaded (or terminated). If this is done frequently, it would significantly affect the performance of the client application. Therefore the client could choose to artificially increment the server's lock count by invoking LockServer
on the server. Consequently, even when the last reference to the component is released, the server continues to remain in memory. The server is unloaded only when the lock applied is again removed by the client.
This means that subsequent requests for a new instance of the object can be resolved to this already running instance of the server.
The typical series of steps that a prospective client could adopt have been listed below.
LockServer
with TRUE
LockServer
with FALSE