How To Pass Large Memory Block Through Win32s Universal Thunk (126708)



The information in this article applies to:

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

This article was previously published under Q126708

SUMMARY

You can share memory between 32-bit code and 16-bit code under Win32s using either GlobalAlloc or passing a memory address to a Universal Thunk (UT) routine. For general information on how to share memory under Win32s, please refer to the following Knowledge Base article:

105762 How To Share Memory Between 32-Bit and 16-Bit Code on Win32s

When you pass a memory address to a thunk routine, the pointer address is translated via the universal thunk (UT). However, the translated pointer is only guaranteed for 32K due to performance reasons. For more information on this limitation, please refer to the following Knowledge Base article:

100833 INFO: Win32s Translated Pointers Guaranteed for 32K

This article describes ways to pass a larger memory block (including greater than 64K in size) through the Universal Thunk under Win32s.

MORE INFORMATION

GlobalAlloc()

You can call GlobalAlloc() to allocate a larger memory block on the 32-bit side of the thunk, copy the data into this memory block, send the handle to the 16-bit side, and lock the handle on the 16-bit side with GlobalLock(). With this method, you are not limited by the size of the block that can be passed across the thunk. If the memory block that you are passing is more than 64K in size, make sure to type cast the return value from GlobalLock() to a huge pointer on the 16-bit side.

VirtualAlloc()or HeapAlloc()

If you allocate the memory using VirtualAlloc(), it will be aligned on a 64K boundary, so that you can address the entire memory block. HeapAlloc() allocates large memory blocks using VirtualAlloc() as well. NOTE: You are still limited to 64K of memory, due to the selector tiling.

Allocate a selector

To use this method, get the 32-bit offset used by the Win32-based application and the selector base for the data selector returned by GetThreadSelectorEntry(), then calculate the linear address of the memory block. With this linear address, you can use AllocSelector(), SetSelectorBase(), and SetSelectorLimit() to access the memory block from the 16-bit side of the thunk.

For more information on converting the linear address to flat offset on Win32s, please refer to the following Knowledge Base article:

115080 How To Convert a Linear Address to a Flat Offset on Win32s

For more information on allocating and using a selector on the 16-bit side, please refer to the following Knowledge Base article:

132005 DOCERR: AllocSelector & FreeSelector Documentation Incomplete

NOTE: Sparse memory will cause problems in the general case. Make sure that the memory range has been not only reserved, but also committed.

Modification Type:MinorLast Reviewed:7/1/2004
Keywords:kbhowto kbprogramming KB126708