2013-04-11 36 views
1

运行32位时,此代码可以正常工作。但是,当我切换到64位GetObject方法不起作用,BITMAP结构是空的。运行64位时gdi32.GetObject不起作用

IntPtr hBmp = ObtainValidBitmapHandleFromSystem(); 
BITMAP bmpData = new BITMAP(); 
/* BITMAP consists of four 32bit ints, 
* two 16 bit uints and one IntPtr */ 
* 4 + sizeof(UInt16) * 2 + IntPtr.Size; 
int cbBuffer = sizeof(Int32) * 4 + sizeof(UInt16) * 2 + IntPtr.Size; 
NativeMethods.GetObject(hBmp, cbBuffer, out bmpData); 

Bitmap bmp = new Bitmap(bmpData.Width, bmpData.Height, PixelFormat.Format32bppPArgb); 

本地方法实现:

private static class NativeMethods 
{ 
    [DllImport("gdi32", CharSet = CharSet.Auto)] 
    internal extern static int GetObject(
     IntPtr hgdiobj,  // handle to graphics object 
     int cbBuffer,  // size of buffer for object information 
     out BITMAP lpvObject // Should be IntPtr, but we know we will use it only for BITMAP. 
    ); 
} 

位图结构的实现(除去文档,以保持代码紧凑):

[StructLayoutAttribute(LayoutKind.Sequential)] 
private struct BITMAP 
{ 
    public Int32 Type; 
    public Int32 Width; 
    public Int32 Height; 
    public Int32 WidthBytes; 
    public UInt16 Planes; 
    public UInt16 BitsPixel; 
    public IntPtr Bits; 
} 

此代码背后的想法是完全在本question描述。

起初我以为,这个问题是由不同大小的IntPtr产生不同大小的cbBuffer造成的,但似乎这是并非如此,因为改变cbBuffer大小没有帮助。

什么是在64位系统上使用GDI的GetObject方法的正确方法?

+0

NativeMethods的外观如何? – Tigran 2013-04-11 13:38:09

+0

@Tigran我编辑了我的问题以包含'NativeMethods'类的一部分。 – SiliconMind 2013-04-11 13:49:48

+0

“不起作用”是什么意思?没有例外吗? – 2013-04-11 13:52:03

回答

3

的问题是这一行:

cbBuffer = sizeof(Int32) * 4 + sizeof(UInt16) * 2 + IntPtr.Size; 

这对32位版本的作品,因为该结构的排列没有填充。但在64位版本中,指针前有4个字节的填充。所以cbBuffer短4个字节。

这就是问题所在。解决办法是自己停止计算大小,并使用专为此目的而设计的Marshal.SizeOf()

+0

如果这样就不足以使用[StructLayout(LayoutKind.Explicit)]和[FieldOffset(OFFSET_NUMBER)]的组合? – Tigran 2013-04-11 14:43:48

+1

@Tigran当标准对齐模式不适合您的结构的实际布局时使用。这些情况在C结构中很少见。他们总是对齐,有时包装。这两者都可以通过'LayoutKind.Sequential'来处理。 'LayoutKind.Explicit'的主要用途是创建一个C联合。那就是当你为所有成员使用'FieldOffset(0)'的时候。附:感谢upvote和成熟的方式,您处理了您现在删除的答案。这里的许多用户会反应不好! – 2013-04-11 14:49:40

+0

谁删除了第一个答案?什么样的特权如此强大? – 2013-04-11 15:00:06