C#, Маршалинг, UNION

Пытаюсь получить структуру MBR записи в удобоваримом формате. Вот описание структур.

[StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct PartitionRecord
    {
        public byte Active;
        public byte FirstHead;
        public byte FirstSectorCylinder;
        public byte FirstCylinder;
        public byte PartitionType;
        public byte LastHead;
        public byte LastSectorCylinder;
        public byte LastCylinder;
        public long FirstSectorOffset;
        public long SectorCount;

    }

    [StructLayout(LayoutKind.Sequential, Pack = 1,Size=512)]
    public struct MBRRecord
    {

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 446)]
        public byte[] Loader;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public PartitionRecord[] PartitionRecords;

        public ushort PartitionSignature;
    }

    [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 512)]
    public struct MBRSector
    {
        [FieldOffset(0)]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
        public byte[] Sector;

        [FieldOffset(0)]
        public MBRRecord Record;
    }

В коде создаю запись

MBRSector mbr=new MBRSector(); mbr.Sector=new byte[512];

читаю данные в mbr.Sector, а когда открываю mbr.Record.Loader, то его размер равен 512 байт и сигнатура не заполнена, хотя в буфере Sector и Loader байты записаны правильно.

С маршалингом еще не сталкивался, подскажите, что я делаю не так?


Ответы (1 шт):

Автор решения: zFire

Разобрался! Для тех, кому возможно пригодиться:

Структуры описал вот так

[StructLayout(LayoutKind.Sequential, Pack = 1, Size=16)]
    public struct PartitionRecord
    {
        [MarshalAs(UnmanagedType.U1)]
        public byte Active;
        [MarshalAs(UnmanagedType.U1)]
        public byte FirstHead;
        [MarshalAs(UnmanagedType.U1)]
        public byte FirstSectorCylinder;
        [MarshalAs(UnmanagedType.U1)]
        public byte FirstCylinder;
        [MarshalAs(UnmanagedType.U1)]
        public byte PartitionType;
        [MarshalAs(UnmanagedType.U1)]
        public byte LastHead;
        [MarshalAs(UnmanagedType.U1)]
        public byte LastSectorCylinder;
        [MarshalAs(UnmanagedType.U1)]
        public byte LastCylinder;
        [MarshalAs(UnmanagedType.U4)]
        public UInt32 FirstSectorOffset;
        [MarshalAs(UnmanagedType.U4)]
        public UInt32 SectorCount;

    }

    [StructLayout(LayoutKind.Sequential, Pack = 1,Size=512)]
    public struct MBRRecord
    {

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 446,
        ArraySubType = UnmanagedType.U1)]
        public byte[] Loader;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public PartitionRecord[] PartitionRecords;

        public ushort PartitionSignature;
    }

Далее в буфер byte[] buff=new byte[512] получаю данные а затем:

IntPtr buffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(mbr));
Marshal.Copy(buff, 0, buffer, 512);
mbr=(MBRRecord)Marshal.PtrToStructure(buffer,typeof(MBRRecord));

Возможно криво, но мне подходит))

→ Ссылка