BUG: MIDL compiler structure packing problems

Last reviewed: May 3, 1996
Article ID: Q136500
The information in this article applies to:
  • Microsoft Win32 SDK, versions 3.1, 3.5, 3.51, and 4.0

SYMPTOMS

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.

CAUSE

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.

RESOLUTION

There are three solutions to correct this problem:

  1. Use MIDL's /Oi option.

    -or-

  2. Use #pragma pack(1) in the stub code to use a packing of 1.

    -or-

  3. Pad your interface declaration to match the padding done by the C compiler.

Please see MORE INFORMATION for details.

STATUS

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.

MORE INFORMATION

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;

Another alternative is to wrap the stub code generated by MIDL with

   #pragma pack(1)

Each time MIDL generates the stub code, you must insert #pragma pack statements into the server stub.

For example:

   /* 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


Additional reference words: 3.50 4.00 95 2.00.0102
KBCategory: kbnetwork kbbuglist kbtool
KBSubcategory: NtwkRpc


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: May 3, 1996
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.