IntPtr to byte array and vice versa

Link How to get IntPtr from byte [] in C #

I am trying to read data that IntPtr refers to byte [] and then back to another IntPtr. The pointer refers to the image taken from the scanner device, so I also made the assumption that the capture of this information should be placed in an array of bytes.

I'm also not sure if the Marshal.SizeOf () method will return the size of the data that IntPtr refers to, or the size of the pointer itself.

My problem is that I get the error "Type" System.Byte [] 'cannot be marshaled as an unmanaged structure, without a significant size or offset it can be calculated "

IntPtr bmpptr = Twain.GlobalLock (hImage); try { byte[] _imageTemp = new byte[Marshal.SizeOf(bmpptr)]; Marshal.Copy(bmpptr, _imageTemp, 0, Marshal.SizeOf(bmpptr)); IntPtr unmanagedPointer = Marshal.AllocHGlobal( Marshal.SizeOf(_imageTemp)); try { Marshal.Copy(_imageTemp, 0, unmanagedPointer, Marshal.SizeOf(_imageTemp)); Gdip.SaveDIBAs( string.Format("{0}\\{1}.{2}", CaptureFolder, "Test", "jpg"), unmanagedPointer, false); } finally { Marshal.FreeHGlobal(unmanagedPointer); } } catch (Exception e) { Scanner.control.Test = e.Message; } 
+6
c # interop marshalling intptr
source share
2 answers

The exception SizeOf call is true; the method has no way of knowing how long the array you are going to is just a pointer.

To this end, the easiest way to get data is to call the static Copy method in the marshal’s class , passing a pointer to unmanaged data, the index and number of bytes read, as well as a pre-allocated byte buffer for marshaling data.

Regarding getting the size of the array, as Anton Twain.GlobalLock(hImage) noted in the comments , (very carefully here) that calling Twain.GlobalLock(hImage) uses the memory allocated by GlobalAlloc , which means that you can make a call to the GlobalSize API function through the P / Invoke layer to get the size.

If this is not a handle to something allocated by calling GlobalAlloc , you need to find out how the Twain module allocates memory and uses the appropriate mechanism to determine the memory length that IntPtr points to.

+6
source share

1- I assume that bmpptr already an unmanaged pointer, so why do you need to bypass it back to the unmanagedPointer unmanaged pointer?

2 Marshal.SizeOf will not give you the size of unmanaged memory allocation.

Using Marshal.Copy, you can copy the contents of unmanaged memory into a managed byte array, but you need to know how many bytes you need to move from the unmanaged buffer to the managed buffer. The API should ideally provide this information.

+2
source share

All Articles