Marshal.PtrToStructure访问冲突

时间:2016-08-01 16:03:39

标签: c#

谁能明白为什么会失败?如果我用“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:尝试读取或写入受保护的内存。这通常表明其他内存已损坏。

     

at System.Runtime.InteropServices.Marshal.PtrToStructure(IntPtr ptr,Type structureType)

     

在D:\ data \ Projects \ Test \ Test \ Program.cs中的Program.Core.Main(String [] args):第41行

1 个答案:

答案 0 :(得分:2)

可能是因为您使用了错误的签名吗?

[的DllImport(" GDI32.DLL&#34)] static extern int GetObject(IntPtr hgdiobj,int cbBuffer,IntPtr lpvObject);

http://www.pinvoke.net/default.aspx/gdi32/GetObject.html

此外, out 意味着该值需要在方法中初始化,并且可能没有发生,因为您已经定义了 lpvObject