例如,是这个结构的unmanged内存布局:
public struct MyStruct<T>
where T: unmanaged
{
public T pointer;
}
和普通的一样
T
?
此外,他们在调用
Marshal.PtrToStructure
和Marshal.StructureToPtr
时的行为是否相同?
也就是说,这行得通吗?
MyStruct<int> myStruct;
IntPtr pointer = Marshal.AllocHGlobal(Marshal.SizeOf(MyStruct<int>));
Marshal.StructureToPtr(myStruct, pointer, false);
int myStructField = Marshal.PtrToStructure<int>(pointer);
这在理论上取决于您拥有的 CLR 版本。通常是的,在托管内存中,结构由一组顺序字段表示。然而,特别是对于局部变量,单个字段可能会被放入寄存器或其他地方(甚至优化掉),并且也可能发生多个字段重新排序。
你永远不能依赖一个特定的实现不随着版本的不同而改变。
理论上,符合规范的 CLR 实现可以自由地以任何它认为合适的方式安排内存。 我的 .NET 私有实现将数据存储在由奶酪制成的月球上。(堆栈由带有手写笔记的披萨盒组成,以防您想知道)。
就互操作而言,结构总是以定义的方式编组。
StructLayoutAttribute
受到尊重:它是规范的一部分,不太可能更改。请注意,如果您不指定该属性,那么 CLR 可以自由地重新排序或重新打包它,这就是为什么您应该always 为互操作代码指定它。
因此,如果您指定
LayoutKind.Sequential
,则字段将从偏移量 0 开始对齐,并根据应用程序的位数(或指定)打包。