为什么atmel处理器上的mono不能很好地与LayoutKind.Explicit配合使用?

为什么atmel处理器上的mono不能很好地与LayoutKind.Explicit配合使用?,mono,arm,atmel,layoutkind.explicit,Mono,Arm,Atmel,Layoutkind.explicit,我创建了一个类似贝娄的结构: [StructLayout(LayoutKind.Explicit, Pack = 1)] public class NodRecord { [FieldOffset(0)] public ushort Driver; [FieldOffset(2)] public ushort BaudRate; [FieldOffset(4)] public u

我创建了一个类似贝娄的结构:

[StructLayout(LayoutKind.Explicit, Pack = 1)]
    public class NodRecord
    {
        [FieldOffset(0)]
        public ushort Driver;


        [FieldOffset(2)]
        public ushort BaudRate;

        [FieldOffset(4)]
        public ushort EnquiryInterval;

        [FieldOffset(6)]
        public byte Protocol;

        [FieldOffset(7)]
        public ushort Delay;

        [FieldOffset(9)]
        public NodIPAddress IP_Addr_Other;

        [FieldOffset(13)]
        public ushort IP_Port_Other;

        [FieldOffset(15)]
        public ushort IP_Port_Own;

        [FieldOffset(17)]
        public ushort Application;
    }
然后我读了下面的代码:

 readBuffer = reader.ReadBytes(sizeType);
 handle = GCHandle.Alloc(readBuffer, GCHandleType.Pinned);
 nodes = (NodRecord)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(NodRecord));
 handle.Free();
我很惊讶x86、x64和cortex arm处理器一切正常,但在Atmel ARM9 AT91SAM9G20上,对于
ushort
变量,我得到了错误的值,例如,第一个和第三个next字节值替换为第一个和第二个next字节,但对于字节值一切正常

一些旧的arm处理器(还有一些新的,取决于它们的配置和操作系统)当涉及到任何未对齐的地址时,它们的概念是不正确的:它们不会出错,也不会在指定的地址加载值。它们所做的是(我忘记了细节)某种无意识的旋转或地址对齐,从而使数据与您不同(或任何其他人)期待它。 Mono不能很好地处理这种情况(这意味着所有表现良好的情况下的代码都会变慢,因此我们做出了权衡,让几乎所有人都能享受这种速度,少数人处理边缘情况)。
您有两种可能的解决方案:查看您使用的操作系统是否具有使内核处理此类情况的配置选项,或者通过逐字节加载并在有未对齐数据时移动以合并值来实现这种情况下的封送处理,前提是您能在代码生成时确定加载是否有效无论是否为ned,您都可以根据需要生成快速或慢速代码。这里的关键是,结构及其字段被清楚地标记为处于任意字节对齐状态,因此您知道必须逐字节生成序列。无论如何,您都将为存储区生成此序列。如果是如此简单……在代码生成时,您可以不知道数据是否对齐(例如,即使字段对齐,结构也可以存储在内存中未对齐的地址)因此,我们必须始终为所有结构访问生成缓慢的代码。即使在其工作的平台上,使用上述布局也是一种不好的做法,因此无论如何都应该避免。如果结构为Pack=1,则您知道该结构可能存储在未对齐的地址,您需要处理该问题。如果结构不是Pack=1您可以假设它具有默认对齐方式。它与GCC对打包访问的支持没有什么不同。几十年的经验表明,当程序员明确要求未对齐的访问时,这可以以合理的效率实现,而不会以任何方式损害默认对齐数据的效率,即使在“非托管”环境中像C这样的语言。即使没有Pack=1或显式布局,结构也可以存储在未对齐的地址。但是,无论如何,如果您认为这很容易,并且实现对于好的代码和数据结构没有任何性能缺陷,我愿意尝试您的补丁,或者编写一个破坏它的测试,或者ws导致性能下降。