0

我有一个 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)]在结构之上,但删除它并不会破坏我的代码。

提前致谢

4

1 回答 1

1

这个...

Marshal.ReadIntPtr(myIntPtr)

...返回一个IntPtr,顾名思义。当传递给Marshal.SizeOf()...

var size = Marshal.SizeOf(Marshal.ReadIntPtr(myIntPtr));

...它不返回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);

我认为这不会对任何事情产生负面影响(而不是如果你ToInt32()在 64 位进程中调用,这可能会抛出一个OverflowException),但最好让IntPtr处理计算指向每个MyStruct元素的指针,你可以这样...

IntPtr iP = IntPtr.Add(myIntPtr, i * size);

...或者只是这个...

IntPtr iP = myIntPtr + i * size;
于 2021-12-30T17:39:09.157 回答