The ATL COM AppWizard relies on the ATL CComModule class for much of the required server implementation. CComModule is implemented in atlbase.h, which is included in stdafx.h. Regardless of your choice of server (DLL or EXE), an instance of CComModule will be created in your main .cpp file with the name _Module. EXE servers use a derivative of CComModule that we'll look at when we discuss server lifetime. ATL classes are tightly coupled to the _Module instance name, so you must not change the name. A pointer to this single instance is also cached in atlbase.h in the _pModule global variable so that other classes implemented in atlbase.h (such as CComBSTR) can get to the module instance.
At a bare minimum, you need calls to _Module.Init and _Module.Term in your module. These calls bracket the usable lifetime for ATL in your project. In DLL servers, Init is called from the entry point DllMain when the client process is attached, and as you might guess, Term is called when the process is detached. In EXE servers, Init and Term are called in the _tWinMain entry point between CoInitialize and CoUninitialize calls. Init takes three arguments and gives the module a chance to cache the HINSTANCE for the module and a pointer to the object map, which is described later in this chapter. The prototype for Init is shown here:
HRESULT Init(_ATL_OBJMAP_ENTRY* p, HINSTANCE h, const GUID* plibid = NULL)
The ID for the server type library, which you need for self-registration, is passed in as the last argument to Init. Term performs the necessary cleanup work before COM is uninitialized.
We'll be looking at areas of CComModule specific to self-registration, server lifetime, and class objects throughout this chapter.