PRB: DLL Load Fails Under Win32s When Apps Share a DLL (131224)
The information in this article applies to:
- Microsoft Win32s 1.3c
- Microsoft Win32s 1.3
- Microsoft Win32s 1.30a
This article was previously published under Q131224 SYMPTOMS
LoadLibrary fails under Win32s in the following situation:
- App1 is executed and loads MYDLL.DLL.
- App2 is executed and loads MYDLL.DLL as well.
- 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.
Modification Type: | Major | Last Reviewed: | 4/9/2004 |
---|
Keywords: | KB131224 |
---|
|