This is what happens. Your structure is the so-called variable-length structure. Pixel data is contained within a row in the structure, starting from offset to ImageData .
typedef struct abs_image { ABS_DWORD Width; ABS_DWORD Height; ABS_DWORD ColorCount; ABS_DWORD HorizontalDPI; ABS_DWORD VerticalDPI; ABS_BYTE ImageData[ABS_VARLEN]; } ABS_IMAGE
Your API returns pImage , which is an IntPtr that points to unmanaged data of type ABS_IMAGE . However, if you look at the native code, you will see that ABS_VARLEN is 1 . This is because struct must be defined statically at compile time. In fact, the pixel data will have a length determined by height, width, and color.
You can continue to use Marshal.PtrToStructure to get most of the fields. But you cannot get into the ImageData field this way. This will require a little more work.
Instead, declare the structure as follows:
[StructLayout(LayoutKind.Sequential)] public struct ABS_IMAGE { public uint Width; public uint Height; public uint ColorCount; public uint HorizontalDPI; public uint VerticalDPI; public byte ImageData; }
When you need to get image data, follow these steps:
IntPtr ImageData = pImage + Marshal.OffsetOf(typeof(ABS_IMAGE), "ImageData"); Marshal.Copy(ImageData, data, 0, length);
If you have not yet entered .net 4, you need to perform a casting to compile arithmetic:
IntPtr ImageData = (IntPtr) (pImage.ToInt64() + Marshal.OffsetOf(typeof(ABS_IMAGE), "ImageData").ToInt64());
Finally, I think that you are not calculating length correctly. Of course you need to use Height*Width . Also, you did not specify the color depth. For example, a 32-bit color would be 4 bytes per pixel.