【发布时间】:2016-08-01 16:03:39
【问题描述】:
任何人都可以看到它失败的原因吗?如果我用“ref BITMAP lpvObject”替换“out IntPtr lpvObject”,我可以让它以这种方式工作。但我看不出代码有什么问题。
using System;
using System.Runtime.InteropServices;
using System.Drawing;
namespace Program
{
class Core
{
[StructLayout(LayoutKind.Sequential)]
public struct BITMAP
{
public Int32 bmType;
public Int32 bmWidth;
public Int32 bmHeight;
public Int32 bmWidthBytes;
public UInt16 bmPlanes;
public UInt16 bmBitsPixel;
public IntPtr bmBits;
}
[DllImport("gdi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public static extern int GetObject ( IntPtr hgdiobj, int cbBuffer, out IntPtr lpvObject );
static void Main(string[] args)
{
Bitmap TestBmp = new Bitmap ( 10, 10 );
BITMAP BitmapStruct = new BITMAP();
IntPtr pBitmapStruct, pBitmapStructSave;
int Status;
pBitmapStructSave = pBitmapStruct = Marshal.AllocHGlobal ( Marshal.SizeOf(BitmapStruct) );
Status = GetObject ( TestBmp.GetHbitmap(), Marshal.SizeOf (BitmapStruct), out pBitmapStruct );
Console.WriteLine ( "\nBytes returned is " + Status + ", buffer address = " + pBitmapStruct );
try
{
BitmapStruct = (BITMAP) Marshal.PtrToStructure ( pBitmapStruct, typeof(BITMAP) );
}
catch ( Exception Ex )
{
Console.WriteLine ( Ex.Message );
}
Marshal.FreeHGlobal(pBitmapStructSave);
}
}
}
输出是:
返回的字节数为 32,缓冲区地址 = 42949672960
未处理的异常:System.AccessViolationException:试图读取或写入受保护的内存。这通常表明其他内存已损坏。
在 System.Runtime.InteropServices.Marshal.PtrToStructure(IntPtr ptr, Type structureType)
在 D:\data\Projects\Test\Test\Program.cs:line 41 中的 Program.Core.Main(String[] args) 处
【问题讨论】:
-
out IntPtr lpvObject->IntPtr lpvObject -
使用 int GetObject (IntPtr hgdiobj, int cbBuffer, out BITMAP lpobj)。轻松愉快。
-
是的,正如我所说,它也适用于 ref BITMAP。这样做的问题是,当函数返回一个空的第三个参数时,它需要额外的处理。最简单的解决方案仍然是将指针作为输出。无论如何,我需要知道 IntPtr 类型是隐式输出。一千年后我都猜不到。我也不会通过搜索找到它。
标签: c#