The thunk compiler does not support all return value types that the C and C++ languages support. This limitation is caused by the problems of translating addresses from 32-bit address spaces to 16-bit address spaces and vice-versa.
The thunk compiler supports returning all integral types. The signed and unsigned varieties of char, short int, and long int are the same size on both sides of a thunk, so they are returned unmodified. Because integers are 32 bits wide in 32-bit code and 16 bits wide in 16-bit code, values are truncated on return from a 16-bit to 32-bit thunk and sign-extended on return from a 32-bit to 16-bit thunk.
You cannot return a structure from either a 32-bit to 16-bit thunk or a 16-bit to 32-bit thunk. However, pointers to structures can be returned from a 32-bit to 16-bit thunk if the structure does not need to be repacked and does not contain pointers. A structure does not require repacking if the types of all members of the structure are the same size in 16-bit and 32-bit code and the structure is packed with the same alignment on both sides of the thunk. Refer to your compiler documentation for information on specifying structure packing.
You cannot return pointers from 16-bit to 32-bit thunks because the context of the 32-bit address space is not global. The 32-bit address space for the 32-bit DLL is mapped between 4 megabytes and 2 gigabytes, and it is context-switched. This means that a 16-bit Windows-based application or DLL could not use a pointer returned by a 16-bit to 32-bit thunk without causing a general protection (GP) fault. To work around this limitation, write a wrapper function for the 16-bit side of the thunk that allocates memory and passes it to the thunk function as an extra parameter. You should also write a wrapper function for the 32-bit side of the thunk to handle the extra parameter, and copy data to the memory allocated by the 16-bit wrapper.
You can return pointers in 32-bit to 16-bit thunks as long as the base type requires the same number of bytes on both sides of the thunk and does not require repacking. If the size of the base type of a pointer differs between the 16-bit and 32-bit sides, the thunk compiler generates an error. For example, a char is 1 byte on both sides of the thunk, so a pointer to a char is a supported return type. However, an int is 16 bits on the 16-bit side of the thunk and 32 bits on the 32-bit side, so a pointer to an int is not a supported return type.
To return a pointer to a data type whose size is different on the 16-bit and 32-bit sides of a 32-bit to16-bit thunk, write a wrapper function that returns the original type, and have the wrapper pass a buffer to the thunk function as an extra parameter. The target side of the thunk should put the return value into this buffer. After the target side of the thunk returns, the wrapper on the calling side should return the data from the buffer.