The information in this article applies to:
SUMMARYEvery Windows dynamic-link library (DLL) should include a termination function called as a Windows Exit Procedure (WEP) to perform general purpose cleanup operations when Windows unloads a DLL from memory. Under Windows version 3.0, WEPs are not implemented properly; however, under Windows version 3.1, the design of WEPs is enhanced to perform cleanup operations. Also, Microsoft C/C++ versions 7.0 and later provide a default WEP for DLLs in the standard C run-time libraries. This article discusses some issues that relate to WEPs in the various Windows environments. MORE INFORMATIONAs mentioned earlier, every Windows DLL typically includes a Windows Exit Procedure (WEP), which should be the last function called in the last reference to a DLL before the DLL is removed from memory. WEPs under Windows Version 3.0WEPs were introduced in Windows version 3.0 to allow each DLL that hooked interrupts and/or modified I/O ports to clean up when the DLL was unloaded. However, because the initial implementation is flawed and the limitations not well documented, the use of WEPs in Windows version 3.0 is very much limited.WEPs Under Windows Version 3.1Here are some general rules in building WEPs:
Changes to WEPs Under Windows Version 3.1Several changes were made to the implementation of WEPs under Windows version 3.1. The following comprehensive list of changes compares the implementation in Windows 3.0 to that in Windows 3.1:
WEPs Under Microsoft C/C++ Versions 7.0 and LaterAs mentioned earlier, beginning with Microsoft C/C++, the standard C run- time libraries that support DLLs for Windows (xDLLCyW.LIB) contain a default Windows exit procedure WEP(), a default entry-point procedure LibEntry() in the LIBENTRY.OBJ file, and a default library initialization procedure LibMain(). Therefore, if you link to one of the C run-time libraries provided with Microsoft C/C++ versions 7.0 and later, you no longer need to provide your own WEP() or LibMain() routine or link to a LIBENTRY.OBJ file.The LibEntry() procedure in the DLL C run-time libraries performs all the necessary initialization required by the WEPs they contain. The LibEntry() procedure in the default LIBENTRY.OBJ file will call a default LibMain() procedure. The default LibMain() procedure returns and does nothing useful. Remember that no initialization will be done if you use the default LibMain(). However, your DLL could define its own LibMain() function so as to perform any type of additional initialization processing that it needs (for example, registering custom control classes or allocate global memory, and so forth). In such a case, the LibMain() in your DLL will be called instead of the default LibMain() in the run-time library. To use the default run-time library's LibEntry() procedure, just do not link to a LIBENTRY.OBJ file. To use the default run-time library's LibMain() function, do not provide a LibMain() function in your DLL. Similarly, the C run-time libraries call a default version of the WEP function at the time a DLL needs to be unloaded from memory. The source code for the default WEP routine is included in a file called WEP.ASM in the SOURCE\STARTUP\WIN directory of Microsoft C/C++ version 7.0 or later. This default WEP routine just returns and does nothing useful [other than performing some C exit processing by calling _cexit()]. To use the default run-time library's WEP routine, just include the following lines in the .DEF file:
Because the WEP's code is very small, making the WEP_TEXT segment fixed in
memory should not adversely impact Windows's performance.
However, in certain cases there is a need to link into your own WEP routine instead of the default WEP routine provided by the Microsoft C/C++ compiler. This is possible, because the default WEP calls an optional user termination function _WEP. Therefore, to add your own processing to the default WEP function, add a _WEP function as follows:
NOTE: Unlike the default WEP routine, the name of your routine must begin
with a leading underscore. If a _WEP routine is not provided in a DLL, the
default WEP routine will call the default _WEP routine, which simply
returns a 1. In the case where you define your own _WEP routine, LINK.EXE
will resolve references to _WEP to your _WEP instead of the default _WEP
that exists in the DLL C run-time library (as long as you put the object
file that contains your _WEP to the left of the DLL run-time library in the
LINK command line).
NOTE: The default WEP routine provided by the run-time libraries assumes protected-mode operation only because it calls the LAR instruction in its source code, which is a protected-mode instruction only, and therefore will not work in real mode (for example, under Windows 3.0). NOTE: The default WEP provided by the Microsoft C/C++ run-time libraries calls a routine in WIN87EM.DLL, which is the Windows 80x87 floating-point emulation library. Under certain situations, the WIN87EM library might have been unloaded from memory by the time the default WEP routine is called. If this causes problems, copying WIN87EM.DLL to WIN87EM.EXE and placing it on the LOAD= line of WIN.INI will ensure the usage count of WIN87EM will never reach zero. NOTE: Avoid making recursive calls or calling MS-DOS functions or using file I/O in the _WEP routine, if you provide one in the DLL. NOTE: Because the initialization and termination operations performed by the LibEntry and WEP functions in the C run-time libraries are correlated, you should use them both, or neither. If you use your own WEP, then you should link to LIBENTRY.OBJ; if you use the C run-time library's WEP, you should use its LibEntry as well. For more information, refer to the DETAILS.TXT file that is shipped with Microsoft C/C++ version 7.0 or later. Additional query words: 3.10
Keywords : kb16bitonly |
Last Reviewed: November 10, 1999 © 2000 Microsoft Corporation. All rights reserved. Terms of Use. |