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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
调用
引发的异常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 byGlobalAlloc
, which means that you can make a call to theGlobalSize
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 theTwain
module is allocating the memory and use the appropriate mechanism to determine the length of the memory pointed to by theIntPtr
.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 pointerunmanagedPointer
?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.