IntPtr到字节数组和返回

引用如何从C#中的byte []获取IntPtr

我试图读取IntPtr引用到byte []然后再返回另一个IntPtr的数据。 指针正在引用从扫描仪设备捕获的图像,因此我还假设捕获此信息应放入字节数组中。

我也不确定Marshal.SizeOf()方法是否会返回IntPtr引用的数据大小或指针本身的大小。

我的问题是我收到错误“类型’System.Byte []’无法编组为非托管结构;无法计算有意义的大小或偏移量”

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

调用SizeOf引发的exception是正确的; 该方法无法知道传递给它的数组的长度是多少,它只有一个指针。

为此,获取数据的最简单方法是在Marshal类上调用静态Copy方法 ,将指针传递给非托管数据,索引和要读取的字节数,以及预先分配的字节缓冲区将数据整理成。

至于获取数组的大小,正如Anton Tykhyy在评论中所指出的那样 (在这里非常小心)调用Twain.GlobalLock(hImage)正在使用GlobalAlloc分配的内存,这意味着你可以创建一个通过P / Invoke层调用GlobalSize API函数来获取大小。

如果它不是通过调用GlobalAlloc分配的东西的句柄,那么你需要找出Twain模块如何分配内存并使用适当的机制来确定IntPtr指向的内存长度。

1-我假设bmpptr已经是一个非托管指针,如果是这样,为什么你需要’往返’回到非托管指针unmanagedPointer

2- Marshal.SizeOf不会给你非托管内存分配的大小。

使用Marshal.Copy,您可以将非托管内存的内容复制到托管字节数组,但您需要知道需要将多少字节从非托管缓冲区移动到托管缓冲区。 理想情况下,API应提供此信息。