Summary: Begin initialization code with the .STARTUP directive.
A DLL can contain procedures that require special resources, such as temporary files or dynamic memory blocks. Resources allocated during initialization exist for the lifetime of the client program and are removed when the client program exits. Usually the best method for managing these resources is to write initialization and termination code.
A DLL can have a starting point just as an application does. In the case of a DLL, this starting point marks the beginning of the initialization code. A DLL does not need a starting point if it has no need for initialization. Do not use .EXIT, since .EXIT will terminate the client program.
Attributes of the initialization code are defined in the module-definition file
(see Section 18.4.1). Initialization code can have the INITGLOBAL or
INITINSTANCE attribute.
INITGLOBAL specifies that the initialization code executes only once—when the DLL is first loaded into memory. INITINSTANCE specifies that initialization code should execute once for each program that uses the DLL. INITGLOBAL is the default. You should use termination code only for DLLs that have been defined with INITINSTANCE unless you know that the first process to use the DLL is the last to terminate.
To specify INITINSTANCE, place the LIBRARY statement in your module-definition file:
LIBRARY CSTR INITINSTANCE
In the statement above, CSTR is the name of the DLL.
To include a termination procedure, invoke DosExitList in the initialization code. DosExitList is a system function that attaches a termination procedure to a program. When the program terminates, OS/2 executes the procedure as part of the program exit sequence. In the termination procedure itself, release any system resources (such as memory or files) allocated during initialization.
This is the termination code for the CSTR.DLL module:
CStrExit PROC FAR <LOADDS, FORCEFRAME>
INVOKE VioWrtCStr,
ADDR szOut,
0
INVOKE DosExitList, EXLST_EXIT, 0
CStrExit ENDP
The termination code in CSTR.DLL uses the INVOKE directive to set up a call to the DosExitList function. You can perform a similar operation by simply pushing arguments on the stack and observing the correct calling convention.
The effect of DosExitList in the initialization code is to make OS/2 call the termination procedure when the current process exits. The “current process” in this case is the client program, not the DLL or the DLL initialization code.