Почему моно на процессорах Atmel не работает с LayoutKind.Explicit?

Я создал структуру, как показано ниже:

[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 переменные, которые я получил неправильные значения, например, первый и третий следующие байты заменяют вместо первого и второго следующих байтов, но для байтовых значений все в порядке

1 ответ

Некоторые старые процессоры ARM (и некоторые новые, в зависимости от их конфигурации и операционной системы) имеют неверную концепцию, когда речь идет о любом невыровненном адресе: они не отказывают и не загружают значение по указанному адресу. То, что они делают, - это (я забыл детали) своего рода бессмысленное вращение или выравнивание адреса, чтобы данные появлялись в отличие от вас (или кого-либо еще), ожидающих этого. Mono плохо справляется с этим делом (это будет означать замедление кода для всех хороших примеров, поэтому мы сделали компромисс, чтобы почти все могли наслаждаться скоростью, а несколько человек занимаются дополнительными случаями). У вас есть два возможных решения: посмотреть, имеет ли используемая вами операционная система параметр конфигурации, который заставляет ядро ​​работать с такими случаями, или самостоятельно выполнить маршалинг для этого случая, загружая побайтово-байтовое и сдвигая, чтобы объединить значения, когда у вас есть невыровненные данные

Другие вопросы по тегам