PRB: DLL Load Fails Under Win32s When Apps Share a DLL

ID: Q131224

1.30 1.30a 1.30c WINDOWS kbprg kbprb

The information in this article applies to:

SYMPTOMS

LoadLibrary fails under Win32s in the following situation:

1. App1 is executed and loads MYDLL.DLL.

2. App2 is executed and loads MYDLL.DLL as well.

3. App1 is terminated and unloads MYDLL.DLL.

App2 can GP fault when MYDLL.DLL is accessed. In addition, if App1 is restarted and attempts to load MYDLL.DLL, the call to LoadLibrary fails and GetLastError reports ERROR_DLL_INIT_FAILED.

This problem does not occur under Windows NT or Windows 95.

CAUSE

By default, Visual C++ creates a DLL that statically links to the C Run- time (CRT) using either the LIBC.LIB or LIBCMT.LIB file to resolve external symbols depending on whether single-threaded (/ML option) or multi-threaded (/MT option) version was used. This version of the CRT library is not compatible with Win32s. Problems occur when global data for the CRT is initialized, because of the shared address space under Windows.

The static CRT library uses global variables to manage memory allocations. In the scenario above, App2 can fault when allocating memory, if the global variables used to access memory refer to memory that was allocated App1 which has since terminated, because the allocated memory was returned to the heap.

RESOLUTION

Use the /MD (Multithreaded using CRT in a DLL) option when compiling the DLL and add the MSVCRT.LIB import library to the library list. Include the Win32s version of MSVCRT20.DLL or MSVCRT40.DLL which is included in Visual C++ 2.x or 4.x(it is redistributable) in your project. Then the DLL will use the DLL version of the CRT libraries that is compatible with Win32s and the problem will not occur.

MORE INFORMATION

When a DLL that uses the CRT is loaded into memory, all global variables for the DLL and for the CRT libraries are initialized. Under Windows NT and Windows 95, the application is given its own copy of the global data for the DLL. When other applications use the same DLL, they each receive their own copy of the global variables as well. This eliminates conflicts, because the data is not shared.

Under Win32s, DLLs are loaded into the same shared memory space and all global variables for a DLL are shared. This means that the CRT global data is also shared. The version of MSVCRT20.DLL that targets Win32s was written to take this into account and avoid conflicts.

The Windows NT/Windows 95 version of MSVCRT20.DLL or MSVCRT40.DLL can be found in the MSVC20\REDIST or MSVC40\REDIST directory of the CD. The Win32s version can be found in the WIN32S\REDIST directory.

KBCategory: kbprg kbprb KBSubcategory: W32s Additional reference words: 1.30 1.30a 1.30c

Keywords          : kbWin32s 
Version           : 1.30 1.30a 1.30c
Platform          : WINDOWS

Last Reviewed: January 8, 1997