Calling a Win32 DLL from a Win16 App on Win32s (97785)



The information in this article applies to:

  • Microsoft Win32s 1.3c
  • Microsoft Win32s 1.1
  • Microsoft Win32s 1.2
  • Microsoft Win32s 1.3
  • Microsoft Win32s 1.30a

This article was previously published under Q97785

SUMMARY

A Windows version 3.1 application can call a Win32 dynamic-link library (DLL) under Win32s using Universal Thunks.

The following are required components (in addition to the Windows 3.1 application and the Win32 DLL):

  • A 16-bit DLL that provides the same entry points as the Win32 DLL. This serves as the 16-bit end for the Universal Thunk. The programmer must also include code that will detect whether the 32-bit side is loaded.
  • A Win32 DLL that sets up the Universal Thunk. This serves as the 32-bit end of the Universal Thunk. This DLL is supported only under Win32s.
  • A Win32 EXE that loads the 32-bit DLL described above.
NOTE: Universal Thunks were designed to work with a Win32-based application calling a 16-bit DLL. The method described here has limitations. Because the application is 16-bit, no 32-bit context is created, so certain calls will not work from the Win32 DLL. For example, the first time you call malloc() or new() from a DLL entrypoint called by the 16-bit application, the system will hang. This is because MSVCRT20.DLL is using TLS to store C Run-time state information and there is no TLS set up.

MORE INFORMATION

The following diagram illustrates how the pieces fit together:
                      -----------     -----------     ---------
                     | Win32 EXE |-->| Win32 DLL |<->|  Win32  |
    32-bit           |   (stub)  |   |    (UT)   |   |   DLL   |
                      -----------     -----------     ---------
                              /|\      /|\ 
              -----------------|--------|-------------------------
                               |       \|/ 
                ---------     ------------
               | Win 3.1 |<->| 16-bit DLL |
    16-bit     |   app.  |   |   (UT)     |
                ---------     ------------
				
The load order is as follows: The Windows 3.1 application loads the 16-bit DLL. The 16-bit DLL checks to see whether the 32-bit side has been initialized. If it has not been initialized, then the DLL spawns the 32-bit EXE (stub), which then loads the 32-bit DLL that sets up the Universal Thunks with the 16-bit DLL. Once all of the components are loaded and initialized, when the Windows 3.x application calls an entry point in the 16-bit DLL, the 16-bit DLL uses the 32-bit Universal Thunk callback to pass the data over to the 32-bit side. Once the call has been received on the 32-bit side, the proper Win32 DLL entry point can be called.

Note that the components labeled Win32 DLL (UT) and Win32 DLL in the diagram above can be contained in the same Win32 DLL. Remember that the code in the Win32 DLL (UT) portion isn't supported under Windows NT, so this code must be special-cased if the DLLs are combined.

For more information on Universal Thunks, please see the "Win32s Programmer's Reference" and the documentation for the UTRegister() API.

Modification Type:MajorLast Reviewed:3/15/2004
Keywords:kbThunks KB97785