Непонятное поведение массивов в структуре. Как исправить?

Я создал такую структуру, чтобы снизить вычислительные манипуляции в памяти. Приходящие данные размера 4096 байт записываются в data. А data имеет размер в 16 массивов по 4096 байт. Если инициализировать только data как 16 массивов по 4096 байт, то данные туда записываются. Но при этом остальные поля почему-то тоже получают инициализацию равным 16, в реальности они должны быть по 4096 с учётом выравнивания. А если инициализировать все поля, то возникает конфликт между ними. Пробовал я принудительно выставить для каждого SizeConst. Они, похоже, игнорируют этот параметр. Без инициализации я просто сталкиваюсь с тем, что компилятор ругается на отсутствие инициализации.
Изначальная идея состояла в том, чтобы склеить все 16 массивов по 4096 байт в один массив.
[StructLayout(LayoutKind.Explicit, Pack = 1, Size = 65536)]
    public struct Package
    {
        [FieldOffset(0)]
        [MarshalAs(UnmanagedType.U1)]
        public byte[][] data;

        [FieldOffset(0)]
        [MarshalAs(UnmanagedType.U2)]
        public ushort[] sensor;
        [FieldOffset(8192)]
        [MarshalAs(UnmanagedType.U8)]
        public ulong[] filtered;
        [FieldOffset(40960)]
        [MarshalAs(UnmanagedType.U4)]
        public uint[] registers;

        public byte[] this[int point]
        {
            set { data[point] = value; }
        }
    }
  • Вопрос задан
  • 93 просмотра
Пригласить эксперта
Ответы на вопрос 1
@Sumor
FieldOffset и MarshalAs используются при переводе в неуправляемые структуры (в неуправляемый код) и обратно.
В управляемой памяти эти поля являются ссылочными и в памяти хранятся только ссылки на объекты массивов.
После создания массива data у вас на тот же объект указывает массив sensors (так как FieldOffset одинаковый). Поэтому инициируя data, вы инициируете sensors.
Пересечения остальных массивов в управляемой памяти вы не получите. А при переводе в неуправляемый код можете получить неожиданный результат.

Кстати, для корректного перевода массива, располагающегося в структуре, необходимо использовать следующий синтаксис:
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 65536)]
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы