GetObject返回奇怪的大小

时间:2011-03-15 17:01:19

标签: gdi

这是64位Microsoft C ++ Windows本机代码:

 hIcon = LoadBitmap( hInstance, "InternalIconBase" );
 BITMAP bmp;
 int goret = GetObject(hIcon, sizeof(BITMAP), &bmp);

这失败了,goret == 0。如果我为第三个参数传入null,那么GetObject会告诉你它需要多少字节。它返回32.但sizeof(BITMAP)是28,根据调试器和wingdi.h中的定义:

typedef struct tagBITMAP
  {
    LONG        bmType;
    LONG        bmWidth;
    LONG        bmHeight;
    LONG        bmWidthBytes;
    WORD        bmPlanes;
    WORD        bmBitsPixel;
    LPVOID      bmBits;
  } BITMAP, *PBITMAP,  *NPBITMAP,  *LPBITMAP;

它的大小肯定是28字节(4 * 4字节,2 * 2字节,8字节)!我们显然肯定加载了一个BITMAP,这个页面上的文档http://msdn.microsoft.com/en-us/library/dd144904.aspx表示,对于这样一个句柄,它将返回BITMAP(28为28)或DIBSECTION(为92)的大小。并且文档页面上的其他任何返回类型都没有任何接近32的大小。

而LoadBitmap和GetObject只是简单的GDI方法(没有重载或任何东西)。

我们的代码确实在字节边界上使用/ Zp1打包东西,这可以解释为什么它适用于32位代码但不适用于64位代码。虽然通常Microsoft头文件推送打包设置并再次恢复它?可能某种程度上GDI头文件中缺少这个?

1 个答案:

答案 0 :(得分:1)

确实,因为如果我这样做似乎工作正常:

//wingdi.h does not set the proper pack setting, causing structures to have the wrong size due to our /Zp1!
//32-bit: sizeof(BITMAP)==24
//32-bit: sizeof(BITMAP)==28 but GetObject says it wants 32, so:
    #ifdef _WIN64
       #pragma pack(push,8)
    #endif
#   include <windows.h>
    #ifdef _WIN64
       #pragma pack(pop)
    #endif