Microsoft KB Archive/105762

From BetaArchive Wiki

HOWTO: Share Memory Between 32-Bit and 16-Bit Code on Win32s


The information in this article applies to:

  • Microsoft Win32s versions 1.3, 1.30a, 1.3c


This article discusses many of the issues involved in sharing memory across the process boundary under Win32s.


Memory allocated by a Win32-based application using GlobalAlloc() can be shared with a 16-bit Windows-based application on Win32s. If the memory is allocated with GMEM_MOVEABLE, then GlobalAlloc() returns a handle and not a pointer. The 16-bit Windows-based application can use the low word of this handle. The high word is all zeros. Make sure to lock the handle using GlobalLock() in the 16-bit Windows-based application to get a pointer.

NOTE: GlobalAlloc (GMEM_FIXED...) is not the same as GlobalFix(GlobalAlloc(GMEM_MOVEABLE...)). GMEM_FIXED will allocate locked pages, which is most often not what you want.

Memory allocated by a 16-bit Windows-based application via GlobalAlloc() must be fixed via GlobalFix() and translated before it can be passed to a Win32-based application. Whenever a Windows object is passed to a Win32-based application by its 32-bit address, the memory must be fixed, because the address is computed from the selector base only once. If Windows moves the memory, the linear address used by the Win32-based application will no longer be valid.

If you are using the Universal Thunk, you can also pass a buffer from a Win32-based application to a 16-bit dynamic-link library (DLL) in the UTRegister() call. The address is translated for you. Another alternative is the translation list passed to the callable stubs. Addresses passed in the translation list will be translated during the thunking process. For more information on the Universal Thunk, please see the "Win32 Programmer's Reference."

NOTE: The ability to share global memory handles under Win32s is a result of the implementation of Windows 3.1, in which all applications run in the same address space. This is not true of existing Win32 platforms and will not be true of future Win32 platforms.

Allocating memory with GlobalAlloc() gets you tiled selectors. However, you can only tile 255 selectors at a time and there is an overall limit of 8192 selectors in the system. If you allocate memory using new, malloc(), HeapAlloc(), LocalAlloc() or VirtualAlloc, your allocated memory does not automatically get you tiled selectors. However, because you don't automatically get tiled selectors, whenever you pass memory to 16-bit code, selectors must be synthesized for you. There's currently a limit of 256 selectors that Win32s maintains for select synthesis. Also note that each block of memory that you pass is limited to 32K in size due to the way that Win32s tiles selectors.


For more information on the limitations of sharing memory between 16-bit and 32-bit code under Win32s, please refer to the following Knowledge Base articles:

Q126708 HOWTO: Pass Large Memory Block Through Win32s Universal Thunk

Q100833 INFO: Win32s Translated Pointers Guaranteed for 32K

Additional query words:

Keywords : kbprogramming kbOSWin32s kbThunks
Issue type : kbhowto
Technology : kbWin32sSearch kbWin32s130 kbWin32s130a kbWin32s130c

Last Reviewed: January 16, 2000
© 2001 Microsoft Corporation. All rights reserved. Terms of Use.