IntPtr 到字节数组并返回

发布于 2024-10-06 15:30:04 字数 1050 浏览 2 评论 0原文

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

我我正在尝试将 IntPtr 引用的数据读入字节 [],然后读回另一个 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;
}

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

I am attempting to read the data that an IntPtr is referencing into a byte [] and then back into another IntPtr. The pointer is referencing an image captured from a scanner device so I have also made the assumption that capturing this information should be placed into a byte array.

I am also not sure if the Marshal.SizeOf() method will return the size of the data the IntPtr is referencing or the size of the pointer itself.

My issue is I am receiving the error "Type 'System.Byte[]' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed"

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

过气美图社 2024-10-13 15:30:04

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

为此,获取数据的最简单方法是调用静态 Copy 方法,将指针传递给非托管数据、要读取的索引和字节数,以及用于封送数据的预分配字节缓冲区。

至于获取数组的大小,正如 Anton Tykhyy 在评论,它似乎(这里要非常小心)对Twain.GlobalLock(hImage)的调用正在使用由GlobalAlloc,这意味着您可以调用 GlobalSize API函数通过P/Invoke层来获取大小。

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

The exception thrown by the call to SizeOf is correct; the method has no way of knowing what the length of the array that you are passing to it is, it just has a pointer.

To that end, the easiest way to get the data is to call the static Copy method on the Marshal class, passing the pointer to the unmanaged data, the index and number of bytes to read, as well as a pre-allocated buffer of bytes to marshal the data into.

As for getting the size of the array, as Anton Tykhyy pointed out in the comments, it appears (be very careful here) that the call to Twain.GlobalLock(hImage) is using 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 it is not a handle to something allocated by a call to GlobalAlloc then you need to find out how the Twain module is allocating the memory and use the appropriate mechanism to determine the length of the memory pointed to by the IntPtr.

治碍 2024-10-13 15:30:04

1-我假设 bmpptr 已经是一个非托管指针,如果是这样,为什么需要将其“往返”回非托管指针 unmanagementPointer

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

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

1- I assume bmpptr is already an unmanaged pointer, if so why do you need to 'round-trip' this back to an unmanaged pointer unmanagedPointer?

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文