繁体   English   中英

从 IntPtr 获取结构数组

[英]Getting Array of struct from IntPtr

我有一些这样的结构

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

我有指向这个结构数组的指针。 所以,我需要从这个指针中获取数组。 我尝试使用 Marshal.PtrToStructure,但出现 memory 读取错误。 这是我的方法:

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

那么,我做错了什么?

两个问题。 在 Marshal.SizeOf() 调用中使用 TCnt 而不是 MyStruct。 您的 IntPtr 算法不能在 64 位机器上运行,您必须使用 IntPtr.ToInt64() 或强制转换为 (long)。

当然,仅仅得到错误的 IntPtr 或长度当然也是有可能的。 使用Debug + Windows + Memory + Memory 1 并将“pointerToStruct”放入地址框中进行基本验证。

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

C 和 C# 中的结构不是一回事。 区别之一是在 C# 中,您必须明确要求您的结构应按顺序布局。 如果您没有为您的结构编写[StructLayout(LayoutKind.Sequential)][StructLayout(LayoutKind.Explicit)]属性,我不相信您可以通过这种方式管理它。 Microsoft 声明PtrToStructure将用于将结构从非托管转换为托管 memory

您应该测试将此属性添加到您的结构是否有帮助,如果它还没有帮助尝试使用Marshal.AllocHGlobal(IntPtr)分配 memory 并使用Marshal.Copy来初始化您的结构,然后尝试使用PtrToStructure 如果这可行,那么您不能将PtrToStructure与托管 memory 一起使用

暂无
暂无

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

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