c# - IntPtr 到字节数组并返回

标签 c# interop marshalling intptr

引用 How to get IntPtr from byte[] in C#

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

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

我的问题是我收到错误“类型‘System.Byte[]’无法作为非托管结构进行编码(marshal)处理;无法计算有意义的大小或偏移量”

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 抛出的异常是正确的;该方法无法知道您传递给它的数组的长度是多少,它只有一个指针。

为此,获取数据的最简单方法是调用静态 Copy method on the Marshal class ,传递指向非托管数据的指针、索引和要读取的字节数,以及用于将数据编码到其中的预分配字节缓冲区。

至于获取数组的大小,如Anton Tykhyy pointed out in the comments ,它似乎(这里要非常小心)对Twain.GlobalLock(hImage) 的调用正在使用由GlobalAlloc 分配的内存,这意味着您可以调用电话 GlobalSize API function通过P/Invoke层获取大小。

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

关于c# - IntPtr 到字节数组并返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4389598/

相关文章:

c# - WPF C# - 如何避免对任务栏图标进行分组?

java - JAXB 2.x : How to override an XmlElement annotation from parent class - Mission Impossible?

c# - 按值将 C# 对象传递给 COM

c# - 是否可以从 .NET 测试暴露于 COM 的程序集?

c# - Outlook Interop C# 排序项目不起作用

c# - 附加到现有的 Excel 实例

c# - 有条件地加入 Linq

c# - 无法将图像渲染到 HttpContext.Response.OutputStream

c# - 如何使用与 X509Chain (C#) 不同的东西来检查证书中的 CRL?

java - 使用JNA将 native C函数映射到Java接口(interface)时出现指针问题