GetObject 返回奇怪的大小

发布于 2024-10-22 05:48:47 字数 1028 浏览 3 评论 0原文

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

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

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

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 字节)!我们显然正在加载位图,并且此页面上的文档 http://msdn .microsoft.com/en-us/library/dd144904.aspx 表示,对于这样的句柄,它将返回 BITMAP 的大小(即 28)或 DIBSECTION(即 92)。文档页面上的其他返回类型的大小都没有接近 32。LoadBitmap

和 GetObject 只是普通的 GDI 方法(没有重载或任何东西)。

我们的代码确实在字节边界上使用了 /Zp1 打包内容,这可以解释为什么它适用于 32 位代码而不适用于 64 位代码。虽然微软头文件通常会推送打包设置并再次恢复它?也许 GDI 头文件中缺少这个?

This is 64-bit Microsoft C++ Windows native code:

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

This fails, goret==0. If I pass in null for the third argument, then GetObject tells you how many bytes it needs. It returns 32. But sizeof(BITMAP) is 28, according to the debugger and the definition in wingdi.h:

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

Its size surely is 28 bytes (4*4 bytes, 2*2 bytes, 8 bytes)! We are clearly definitely loading a BITMAP, and the documentation on this page http://msdn.microsoft.com/en-us/library/dd144904.aspx says that for such a handle it will return either the size of BITMAP (which is 28) or DIBSECTION (which is 92). And none of the other return types on the documentation page has a size anywhere near 32.

And LoadBitmap and GetObject are just the plain GDI methods (no overloading or anything).

Our code does make use of /Zp1 packing stuff on the byte boundary, which could explain why it works on 32-bit code but not 64-bit code. Though usually Microsoft header files push the packing setting and restore it again? Maybe that is missing from the GDI header files somehow?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

反目相谮 2024-10-29 05:48:47

确实,因为如果我这样做,它似乎工作得很好:

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

Indeedy, because it seems to work fine if I do this:

//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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文