从IntPtr获取struct数组
我有一些像这样的结构
struct MyStruct { public int field1; public int field2; public int field3; }
我有指向此结构数组的指针。 所以,我需要从这个指针获取数组。 我试图使用Marshal.PtrToStructure,但我有内存读取错误。 这是我的方法:
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”进行基本validation。
假设结构的大小是固定的 ,这个函数对我有用:
public static void MarshalUnmananagedArray2Struct(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 (ins); } }
C和C#中的结构不是一回事。 其中一个不同之处在于,在C#中,您必须明确要求您的结构应按顺序排列。 如果您没有将[StructLayout(LayoutKind.Sequential)]
或[StructLayout(LayoutKind.Explicit)]
属性写入您的结构,我不相信您可以通过这种方式管理它。 Microsoft声称PtrToStructure
将用于将结构从非托管内存转换为托管内存
您应该测试是否将这些属性添加到您的结构中有帮助,如果它还没有帮助尝试使用Marshal.AllocHGlobal(IntPtr)
分配内存并使用Marshal.Copy
来初始化您的结构,然后尝试使用PtrToStructure
。 如果这样PtrToStructure
,那么就不能将PtrToStructure
与托管内存一起使用