简体   繁体   English

从 IntPtr 获取结构数组

[英]Getting Array of struct from IntPtr

I have some struct like this我有一些这样的结构

struct MyStruct
{
    public int field1;
    public int field2;
    public int field3;
}

and I have pointer to array of this struct.我有指向这个结构数组的指针。 So, I need to get array from this pointer.所以,我需要从这个指针中获取数组。 I'm tried to using Marshal.PtrToStructure, but i had memory reading error.我尝试使用 Marshal.PtrToStructure,但出现 memory 读取错误。 This is my methode:这是我的方法:

public MyStruct[] GetArrayOfStruct(IntPtr pointerToStruct, int length)
{
    var sizeInBytes = Marshal.SizeOf(typeof(TCnt));
    MyStruct[] output = new MyStruct[length];

    for (int i = 0; i < length; i++)
    {
        IntPtr p = new IntPtr((pointerToStruct.ToInt32() + i * sizeInBytes));

        output[i] = (MyStruct)System.Runtime.InteropServices.Marshal.PtrToStructure(p, typeof(MyStruct));
    }

    return output;
}

So, what am i doing wrong?那么,我做错了什么?

Two problems.两个问题。 You use TCnt instead of MyStruct in the Marshal.SizeOf() call.在 Marshal.SizeOf() 调用中使用 TCnt 而不是 MyStruct。 Your IntPtr arithmetic cannot work on a 64-bit machine, you must use IntPtr.ToInt64() or cast to (long).您的 IntPtr 算法不能在 64 位机器上运行,您必须使用 IntPtr.ToInt64() 或强制转换为 (long)。

Just getting the wrong IntPtr or length is certainly a possibility too of course.当然,仅仅得到错误的 IntPtr 或长度当然也是有可能的。 Use Debug + Windows + Memory + Memory 1 and put "pointerToStruct" in the Address box for basic verification.使用Debug + Windows + Memory + Memory 1 并将“pointerToStruct”放入地址框中进行基本验证。

This function worked for me, assuming that the size of the struct is fixed :这个 function 对我有用,假设结构的大小是固定的

public static void MarshalUnmananagedArray2Struct<T>(IntPtr unmanagedArray, int length, out T[] mangagedArray)
{
    var size = Marshal.SizeOf(typeof(T));
    mangagedArray = new T[length];

    for (int i = 0; i < length; i++)
    {
        IntPtr ins = new IntPtr(unmanagedArray.ToInt64() + i * size);
        mangagedArray[i] = Marshal.PtrToStructure<T>(ins);
    }
 }

Structs in C and C# are not the same thing. C 和 C# 中的结构不是一回事。 One of the differences is that in C# you have to explicitly demand that your struct should be sequentially laid out.区别之一是在 C# 中,您必须明确要求您的结构应按顺序布局。 If you didn't write [StructLayout(LayoutKind.Sequential)] or [StructLayout(LayoutKind.Explicit)] attribute to your structure I don't believe that you can manage it in this way.如果您没有为您的结构编写[StructLayout(LayoutKind.Sequential)][StructLayout(LayoutKind.Explicit)]属性,我不相信您可以通过这种方式管理它。 Microsoft states that PtrToStructure is to be used to convert structures from unmanaged to managed memory Microsoft 声明PtrToStructure将用于将结构从非托管转换为托管 memory

You should test if adding this attributes to your struct helps, If it doesn't yet help try allocating memory with Marshal.AllocHGlobal(IntPtr) and use Marshal.Copy to init your structure and then try using PtrToStructure .您应该测试将此属性添加到您的结构是否有帮助,如果它还没有帮助尝试使用Marshal.AllocHGlobal(IntPtr)分配 memory 并使用Marshal.Copy来初始化您的结构,然后尝试使用PtrToStructure If this works then you can't use PtrToStructure with managed memory如果这可行,那么您不能将PtrToStructure与托管 memory 一起使用

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

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