简体   繁体   English

如何将 IntPtr 转换为结构数组

[英]How to convert an IntPtr to array of structs

I have an IntPtr which is a pointer to an array of structs, and I'm trying to convert it to the array.我有一个 IntPtr,它是一个指向结构数组的指针,我正在尝试将其转换为数组。

I tried我试过了

Marshal.Copy(srcIntPtr, destIntPtrArray, 0, destIntPtrArray.Length);

but after doing the copy, I'm not able to convert the IntPtr's inside of the destination array to the desired structure, while I can convert the srcIntPtr to the structure, which of course only gives me the data of the first index.但是在完成复制之后,我无法将目标数组内部的 IntPtr 转换为所需的结构,而我可以将 srcIntPtr 转换为结构,这当然只会给我第一个索引的数据。 It looks like after doing the copy, the destination array contains a bunch of broken IntPtr's看起来在完成复制之后,目标数组包含一堆损坏的 IntPtr

I also tried我也试过

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

which doesn't throw any error, but the data of the array of structs that I get out of my source IntPtr are not accurate.这不会引发任何错误,但是我从源 IntPtr 中获取的结构数组的数据不准确。

This is the struct that I'm trying to convert to这是我要转换为的结构

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

I have [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] on top of the structs, but removing that doesn't break my code.我在结构顶部有[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] ,但删除它不会破坏我的代码。

Thanks in advance提前致谢

This...这个...

Marshal.ReadIntPtr(myIntPtr)

...returns an IntPtr , as the name implies. ...返回一个IntPtr ,顾名思义。 When passed to Marshal.SizeOf() ...当传递给Marshal.SizeOf() ...

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

...it does not return the size of the MyStruct to which it points but the size of IntPtr for the current process (either 4 or 8 bytes). ...它返回它指向的MyStruct的大小,而是返回当前进程的IntPtr的大小(4 或 8 个字节)。 To get the unmanaged size of MyStruct you need to call SizeOf() like this...要获得MyStruct的非托管大小,您需要像这样调用SizeOf() ...

var size = Marshal.SizeOf<MyStruct>();

...or this... ...或这个...

var size = Marshal.SizeOf(typeof(MyStruct));

Also, the whole point of IntPtr is that it is address width-agnostic, yet you are explicitly retrieving it as a long ...此外, IntPtr的全部意义在于它与地址宽度无关,但您明确地将其检索为long ...

IntPtr iP = new IntPtr(myIntPtr.ToInt64() + i * size);

I don't think that will have a negative effect on anything (as opposed to if you called ToInt32() in a 64-bit process, which could throw an OverflowException ), but it would be better to let IntPtr handle calculating the pointer to each MyStruct element, which you can do like this...我认为这不会对任何事情产生负面影响(与在 64 位进程中调用ToInt32()相反,这可能会引发OverflowException ),但最好让IntPtr处理计算指向的指针每个MyStruct元素,你可以这样做......

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

...or simply this... ...或者只是这个...

IntPtr iP = myIntPtr + i * size;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM