例如,是此 struct 的未管理内存布局:

public struct MyStruct<T>
  where T: unmanaged
{
    public T pointer;
}

和普通的T一样吗?

另外,当他们拨打Marshal.PtrToStructureMarshal.StructureToPtr时,他们的行为是否相同? 就是这样行得通吗?

MyStruct<int> myStruct;
IntPtr pointer = Marshal.AllocHGlobal(Marshal.SizeOf(MyStruct<int>));
Marshal.StructureToPtr(myStruct, pointer, false);
int myStructField = Marshal.PtrToStructure<int>(pointer);

推荐答案

从理论上讲,这取决于您的CLR版本.通常是这样的,在托管内存中, struct 由一组连续的字段表示.但是,特别是使用局部变量时,可能会将单个字段放入寄存器或其他位置(甚至进行优化),而使用多个字段时也可能发生重新排序.

而且,您永远不能依赖于特定的实现不会因版本而改变.

从理论上讲,符合CLR的实现可以自由地以它认为合适的任何方式来安排内存.My private implementation of .NET stores data on the moon, which is made of cheese.个(如果你想知道的话,这一叠是由披萨盒和手写纸条组成的).


就互操作而言, struct 是以定义的方式编组的always.StructLayoutAttribute受到尊重:它是规范的一部分,不太可能改变.请注意,如果您不指定该属性,则CLR可以自由地对其重新排序或重新打包,这就是为什么您应该为互操作代码指定它的原因.

因此,如果您指定LayoutKind.Sequential,则字段将从偏移量0开始对齐,并根据应用程序的位数(或指定的位数)进行打包.

Csharp相关问答推荐

Rx.Net -当关闭序列被触发时如何聚合消息并发出中间输出?

在C#中使用in修饰符

如何告诉自己创建的NuGet包在应用程序中发生了变化?

WPF Windows初始化正在锁定. Net 8中分离的线程

在一个模拟上设置一个方法,该模拟具有一个参数,该参数是一个numc函数表达式

在C#中使用类中的对象值

如何定义EFCore中的多个穿透

无法通过绑定禁用条目

ASP.NET Core AutoMapper:如何解决错误 CS0121调用在以下方法或属性之间不明确

C#中浮点数的System.Text.Json序列化问题

如何在C#中创建VS代码中的控制台应用程序时自动生成Main方法

当我没有此令牌时,为什么语法报告EOF错误?

在使用AWS SDK for.NET时,如何判断S3是否已验证我的对象的校验和?

将C#类导入到PowerShell

错误:此版本的Visual Studio无法打开以下项目

数据库操作预计影响1行,但实际影响0行; after _dbContext.SaveChanges();

如何正确地在VB中初始化类?

如何将 colored颜色 转换为KnownColor名称?

从MudAutoComplete打开对话框,列表仍然可见

除非首先访问使用的终结点,否则本地API上的终结点不起作用