SAMPLE: Win16 App (WOW & Win32s) Calling Win32 DLL Code |
Q114341
1.30 1.30c | 3.51 4.00
WINDOWS | WINDOWS NT
kbprg kbref
The INTEROP sample demonstrates two general methods for calling routines in
a Win32 DLL from a Windows-based application: thunks and SendMessage().
There are two different thunking methods, one for each platform: Generic
Thunks on Windows NT and Universal Thunks on Win32s. The message used is
WM_COPYDATA, a new message introduced by Windows NT and Win32s. All three
methods provide a way to call functions and pass data across the 16-32
boundary, translating any pointers in the process. The advantages of
WM_COPYDATA over thunks are that it is fast and the exact same code runs on
either platform (the thunk mechanism used will depend on the platform). The
disadvantage of WM_COPYDATA is that a method must be devised to get a
function return value (other than true or false) back to the calling
application.
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.
The sample consists of the following source files:
APP16.C - Win16 Application
DLL16.C - 16-bit side of Universal Thunk/Generic Thunk
STUB32.C - 32-bit stub that loads the 32-bit DLLs on Win32s
UTDLL32.C - 32-bit side of the Universal Thunk
DISP32.C - Dispatch calls sent through WM_COPYDATA
DLL32.C - Win32 DLL
This sample is included with the Microsoft Win32 SDK. It is located in the
\MSTOOLS\SAMPLES\Q_A\INTEROP directory.
dll32
---------
| Win32 |
32-bit | DLL |
---------
/|\
----------------|-------
|
--------- ------------
| Win 3.1 |<->| 16-bit DLL |
16-bit | app. | | (GT) |
--------- ------------
app16 dll16
DLL16 is loaded when APP16 is loaded. If it detects that WOW is present,
then it loads DLL32.
DWORD FAR PASCAL LoadLibraryEx32W( LPCSTR, DWORD, DWORD );
DWORD FAR PASCAL GetProcAddress32W( DWORD, LPCSTR );
DWORD FAR PASCAL CallProc32W( DWORD, ..., LPVOID, DWORD, DWORD );
DWORD FAR PASCAL GetVDMPointer32W( LPVOID, UINT );
BOOL FAR PASCAL FreeLibrary32W( DWORD );
When linking the Win16 application, you need to put the following
statements in the .DEF file, indicating that the functions will be imported
from the WOW kernel:
IMPORTS
kernel.LoadLibraryEx32W
kernel.FreeLibrary32W
kernel.GetProcAddress32W
kernel.GetVDMPointer32W
kernel.CallProc32W
Note that although these functions are called in 16-bit code, they need to
be provided with 32-bit handles, and they return 32-bit handles.
stub utdll32 dll32
----------- ----------- ---------
| Win32 |-->| Win32 DLL |<->| Win32 |
32-bit | EXE | | (UT) | | DLL |
----------- ----------- ---------
/|\ /|\
------------------|--------|-------------------------
| \|/
--------- ------------
| Win 3.1 |<->| 16-bit DLL |
16-bit | app. | | (UT) |
--------- ------------
app16 dll16
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.
wParam = (WPARAM) (HWND) hwndFrom; /* handle of sending window */
lParam = (LPARAM) (PCOPYDATASTRUCT) pcds;
Where hwndFrom is the handle of the sending window and COPYDATASTRUCT is
defined as follows:
typedef struct tagCOPYDATASTRUCT {
DWORD dwData;
DWORD cbData;
PVOID lpData;
} COPYDATASTRUCT;
The INTEROP sample uses dwData as a function code, indicating which Win32
DLL entry point should be calling and lpData to contain a pointer to the
data structure to be passed to the function.
disp dll32
----------- ---------
| Win32 |-->| Win32 |
32-bit | EXE | | DLL |
----------- ---------
/|\
------------------|----------------------------------
|
--------- ------------
| Win 3.1 |<->| 16-bit DLL |
16-bit | app. | | (THUNK) |
--------- ------------
app16 dll16
DLL16 is loaded when APP16 is loaded. DISP is spawned to handle WM_COPYDATA
messages, regardless of platform. DISP dispatches the calls to DLL32,
marshaling the arguments.
Additional query words: 1.30 3.51 4.00
Keywords : kbKernBase kbThunks kbOSWin32s kbGrpDSKernBase kbThunks
Issue type :
Technology : kbWin32SDKSearch kbAudDeveloper kbSDKSearch kbZNotKeyword3 kbWin32sSearch kbWin32s130c
|
Last Reviewed: October 22, 1999 © 2001 Microsoft Corporation. All rights reserved. Terms of Use. |