如何将 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;