为什么哦为什么这是不允许的:
private static unsafe byte[] ConvertStruct<T>(T str) where T: struct
{
T* ptr = &str;
int size = Marshal.SizeOf(str);
var arr = new byte[size];
Marshal.Copy((IntPtr) ptr, arr, 0, size);
return arr;
}
我收到编译错误“无法获取托管类型的地址、大小或声明指向托管类型 ('T') 的指针”
或者“结构”约束还不够?从某种意义上说,它仍然可以是托管结构?
我是否正确理解我的结构可能不可直接复制?如果是这样,blittable 不应该是一个有效的约束吗?
就像 Damian_The_Un believer 所说,您不能创建托管对象或包含托管字段的结构的非托管指针。正如我在评论中所说,您无法实现任何通用的限制来确保编译时安全,以确保结构满足这些要求。因此,您无法创建指向泛型类型的指针。
不过,可能有一个解决方法。这方法将获取一个结构对象并将其数据复制到IntPtr
地址。您可以将其与Marshall.AllocHGlobal
可能实现您想要的功能:
private static byte[] ConvertStruct<T>(ref T str) where T : struct
{
int size = Marshal.SizeOf(str);
IntPtr arrPtr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(str, arrPtr, true);
var arr = new byte[size];
Marshal.Copy(arrPtr, arr, 0, size);
Marshal.FreeHGlobal(arrPtr);
return arr;
}
正如克里斯·范德莫顿 (Kris Vandermotten) 指出的那样,Marshal.AllocHGlobal
实际上没有必要。您可以固定阵列,获得IntPtr
并复制到IntPtr
直接地:
private static unsafe byte[] ConvertStruct<T>(ref T str) where T : struct
{
int size = Marshal.SizeOf(str);
var arr = new byte[size];
fixed (byte* arrPtr = arr)
{
Marshal.StructureToPtr(str, (IntPtr)arrPtr, true);
}
return arr;
}
不过,第一种方法的好处是它不需要unsafe
工作环境。 (如果你关心这类事情。)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)