user118708
user118708

Reputation: 327

Marshal.PtrToStructure access violation

can anyone see why it's failing ? If I replace "out IntPtr lpvObject" with "ref BITMAP lpvObject", I could get it to work that way. But I just can't see anything wrong with the code as it is.

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);
    }
  }
}

The output is:

Bytes returned is 32, buffer address = 42949672960

Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

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

at Program.Core.Main(String[] args) in D:\data\Projects\Test\Test\Program.cs:line 41

Upvotes: 2

Views: 2206

Answers (1)

MeTitus
MeTitus

Reputation: 3428

Could it be because you're using the wrong signature?

[DllImport("gdi32.dll")] static extern int GetObject(IntPtr hgdiobj, int cbBuffer, IntPtr lpvObject);

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

Also, out means that the value needs to be initializes within the method and that is probably not happening since you already have the lpvObject defined.

Upvotes: 2

Related Questions