BUG: MIDL compiler structure packing problemsID: Q136500
|
An RPC application that uses stub code generated by MIDL throws memory exceptions, causes a general protection (GP) fault, or overwrites memory in the data heap. The RPC application is using a structure or union in the IDL file.
The /Zp (packing) option of the MIDL compiler does not affect the size of
the structure; MIDL always uses a packing of 1. However, the /Zp option of
the C compiler does increase the size of the structure. Because MIDL
assumes a packing of one, it generates code that allocates less memory
than what is actually needed.
You can verify the behavior of the MIDL compiler by searching your client
stub code for _StubMsg.pfnAllocate. This call is present only with semi-
interpreted stubs (the default MIDL option, /Os). Try compiling your IDL
file with different /Zp settings, and notice that the memory allocated by
_StubMsg.pfnAllocate is unchanged, though it should change to accommodate
packing space.
There are three solutions to correct this problem:
Microsoft has confirmed this to be a problem in MIDL 2.00.0102 for the Win32 SDK. This problem has been fixed in MIDL 3.0, now shipping with Windows NT 4.0 beta SDK.
Fully interpreted stubs (MIDL option /Oi) use another approach for
parameter marshaling, and this alternative approach does not have the
problem with the packing. The stub code produced with /Oi is slightly
slower, but for most applications the loss is negligible. If you decide to
use the /Oi option, make sure your remote procedures are declared as
__stdcall. Refer to the MIDL documentation for more information on /Oi.
If you are not interested in using the /Oi option, you can manually pad
your interface declaration. To manually pad your interface declaration,
you must first determine the packing used by the C compiler. Visual C++
2.x for the x86 uses a packing of 4 by default. Otherwise, the packing is
specified by /Zp or #pramga pack(). Each element must start on a multiple
of the packing size.
The following example shows how to pad a structure with a packing of 4.
typedef struct // This struct goes in the C code
{
char c;
long l;
} PADDED_BY_COMPILER_STRUCT;
typedef struct // This struct goes in the IDL file
{
char c;
char pad[3]; // Add 3 bytes to align the next field on byte 4
long l;
} MANUALLY_PADDED_IDL_STRUCT;
#pragma pack(1)
/* File created by MIDL compiler version 2.00.0102 */
/* at Fri Aug 18 13:48:23 1995
*/
//@@MIDL_FILE_HEADING( )
#pragma pack(1) // Added to fix MIDL pack problem
#include <string.h>
#include "bug.h"
... code generated by MIDL ...
#pragma pack() // Added to revert to default packing
Keywords : kbnetwork kbAPI kbNTOS310bug kbNTOS350bug kbNTOS351bug kbRPC kbSDKPlatform kbWinOS95bug kbGrpNet
Version :
Platform :
Issue type : kbbug
Last Reviewed: March 7, 1999