如何将 IntPtr 转换为结构数组
How to convert an IntPtr to array of structs
我有一个 IntPtr,它是一个指向结构数组的指针,我正在尝试将它转换为数组。
我试过了
Marshal.Copy(srcIntPtr, destIntPtrArray, 0, destIntPtrArray.Length);
但是在完成复制之后,我无法将目标数组内部的 IntPtr 转换为所需的结构,而我可以将 srcIntPtr 转换为结构,当然这只会给我数据第一个索引。
看起来在完成复制之后,目标数组包含一堆损坏的 IntPtr
我也试过了
var size = Marshal.SizeOf(Marshal.ReadIntPtr(myIntPtr));
for (int i = 0; i < length; i++)
{
IntPtr iP = new IntPtr(myIntPtr.ToInt64() + i * size);
MyStruct ms =
(MyStruct ) Marshal.PtrToStructure(iP, typeof(MyStruct ));
}
这不会引发任何错误,但我从源 IntPtr 中获取的结构数组数据不准确。
这是我要转换成的结构
struct MyStruct
{
public Categories categories;
public Dimensions dimensions;
}
public struct Categories {
public double d;
public double c;
public double b;
public double a;
}
struct Dimensions {
public double v;
public double e;
}
我在结构顶部有 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
,但删除它不会破坏我的代码。
提前致谢
这个...
Marshal.ReadIntPtr(myIntPtr)
...return 一个 IntPtr
,顾名思义。当传递给 Marshal.SizeOf()
...
var size = Marshal.SizeOf(Marshal.ReadIntPtr(myIntPtr));
...它 不是 return 它指向的 MyStruct
的大小,而是 IntPtr
的大小当前进程(4 或 8 字节)。要获得 MyStruct
的非托管大小,您需要像这样调用 SizeOf()
...
var size = Marshal.SizeOf<MyStruct>();
...或者这个...
var size = Marshal.SizeOf(typeof(MyStruct));
此外,IntPtr
的全部意义在于它与地址宽度无关,但您明确地将其检索为 long
...
IntPtr iP = new IntPtr(myIntPtr.ToInt64() + i * size);
我认为这不会对任何事情产生负面影响(相对于如果您在 64 位进程中调用 ToInt32()
,这可能会引发 OverflowException
),但是它最好让 IntPtr
处理计算指向每个 MyStruct
元素的指针,您可以这样做...
IntPtr iP = IntPtr.Add(myIntPtr, i * size);
...或者只是这个...
IntPtr iP = myIntPtr + i * size;
我有一个 IntPtr,它是一个指向结构数组的指针,我正在尝试将它转换为数组。
我试过了
Marshal.Copy(srcIntPtr, destIntPtrArray, 0, destIntPtrArray.Length);
但是在完成复制之后,我无法将目标数组内部的 IntPtr 转换为所需的结构,而我可以将 srcIntPtr 转换为结构,当然这只会给我数据第一个索引。 看起来在完成复制之后,目标数组包含一堆损坏的 IntPtr
我也试过了
var size = Marshal.SizeOf(Marshal.ReadIntPtr(myIntPtr));
for (int i = 0; i < length; i++)
{
IntPtr iP = new IntPtr(myIntPtr.ToInt64() + i * size);
MyStruct ms =
(MyStruct ) Marshal.PtrToStructure(iP, typeof(MyStruct ));
}
这不会引发任何错误,但我从源 IntPtr 中获取的结构数组数据不准确。
这是我要转换成的结构
struct MyStruct
{
public Categories categories;
public Dimensions dimensions;
}
public struct Categories {
public double d;
public double c;
public double b;
public double a;
}
struct Dimensions {
public double v;
public double e;
}
我在结构顶部有 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
,但删除它不会破坏我的代码。
提前致谢
这个...
Marshal.ReadIntPtr(myIntPtr)
...return 一个 IntPtr
,顾名思义。当传递给 Marshal.SizeOf()
...
var size = Marshal.SizeOf(Marshal.ReadIntPtr(myIntPtr));
...它 不是 return 它指向的 MyStruct
的大小,而是 IntPtr
的大小当前进程(4 或 8 字节)。要获得 MyStruct
的非托管大小,您需要像这样调用 SizeOf()
...
var size = Marshal.SizeOf<MyStruct>();
...或者这个...
var size = Marshal.SizeOf(typeof(MyStruct));
此外,IntPtr
的全部意义在于它与地址宽度无关,但您明确地将其检索为 long
...
IntPtr iP = new IntPtr(myIntPtr.ToInt64() + i * size);
我认为这不会对任何事情产生负面影响(相对于如果您在 64 位进程中调用 ToInt32()
,这可能会引发 OverflowException
),但是它最好让 IntPtr
处理计算指向每个 MyStruct
元素的指针,您可以这样做...
IntPtr iP = IntPtr.Add(myIntPtr, i * size);
...或者只是这个...
IntPtr iP = myIntPtr + i * size;