18

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. 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 ?

4

3 回答 3

11

这个函数对我有用,假设结构的大小是固定的

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);
    }
 }
于 2016-11-02T09:23:25.723 回答
4

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

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

于 2011-07-19T12:53:21.593 回答
2

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

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

于 2011-07-19T14:00:48.243 回答