微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 使用非对齐数组的编组结构

我试图编组这个结构时遇到异常

[StructLayout(LayoutKind.Explicit,Pack = 1)]
public struct Data
{
    [MarshalAs(UnmanagedType.ByValArray,SizeConst = 4,ArraySubType = UnmanagedType.U1)]
    [FieldOffset(0x1)]
    public byte[] a2;
}

它说
“无法从程序集’WTF,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null’加载类型’WTF.Data’,因为它包含偏移1处的对象字段,该字段未正确对齐或由非对象字段重叠“.

当我将偏移量1更改为0或4时,一切正常.
我究竟做错了什么?

谢谢

解决方法

[StructLayout]会影响结构的托管和封送布局. .NET中的一点怪癖但是创建blittable结构是互操作的一个相当大的胜利,CLR不能忽视托管代码总是在完全不受管理的操作系统上运行的事实.不必创建结构的副本,只是能够将指针传递给托管版本是一个非常重要的性能.

您的[FieldOffset]值违反了.NET内存模型的强大保证,对象引用分配始终是原子的.一个昂贵的单词意味着另一个线程永远不会观察到仅部分更新的无效对象引用.原子性要求正确对齐,在32位模式下为4的倍数,在64位模式下为8.它们未对准,然后处理器可能需要执行多个存储器总线周期以将字节粘合在一起.这很糟糕,当另一个线程也在更新变量时,它会导致撕裂.从旧值中获取指针值的一部分,从新值中获取部分值.剩下的是一个损坏的指针,它会使垃圾收集器崩溃.很坏.

从C#的高级角度来看,模糊的东西,提供基本的执行保证是非常重要的.只要使用LayoutKind.Explicit,就不能将它错位为1,没有解决方法.所以不要使用它.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐