Show / Hide Table of Contents

MSDN.WhiteKnight - Stack Overflow answers

Ответ на "Аналог структуры C++ с битовыми полями в C#"

Answer 1004493

Link

Естественно, это неверно. В С++ 4 битовых поля по 12 бит, расположенных вплотную без пропусков ( __attribute__((packed))). В вашем объявлении для С# 4 обыкновенных поля ushort, накладывающихся друг на друга. Как сделать правильно? В C# нет битовых полей, но есть класс BitConverter и битовые операции, которые позволяют реализовать их.

Битовые маски для установки полей Sync1 и Sync2 выглядят так:

Байт №: |       5|       4|       3|       2|       1|       0| 
                                             00001111 11111111   = 0x0FFF
                                                   Sync1

Байт №: |       5|       4|       3|       2|       1|       0|
                                    11111111 11110000 00000000   = 0xFFF000
                                          Sync2

Это приводит нас к такому коду:

[StructLayout(LayoutKind.Sequential)]
public struct BURInSyncStruct
{
    public static BURInSyncStruct Create()
    {
        BURInSyncStruct s = new BURInSyncStruct();
        s.data = new byte[6];
        return s;
    }

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
    public byte[] data;                       

    public ushort Sync1
    {
        get
        {                    
            byte[] bytes64 = new byte[8];
            Array.Copy(data, bytes64, data.Length);
            ulong x = BitConverter.ToUInt64(bytes64, 0);

            ulong y = x & 0x0FFF;                    
            return (ushort)y;
        }

        set
        {
            byte[] bytes64 = new byte[8];
            Array.Copy(data, bytes64, data.Length);
            ulong x = BitConverter.ToUInt64(bytes64, 0);
            x = x & ~((ulong)0x0FFF);

            ulong y = (ulong)value & 0x0FFF;
            ulong res = x | y;
            bytes64 = BitConverter.GetBytes(res);
            Array.Copy(bytes64, data, data.Length);
        }
    }

    public ushort Sync2
    {
        get
        {
            byte[] bytes64 = new byte[8];
            Array.Copy(data, bytes64, data.Length);
            ulong x = BitConverter.ToUInt64(bytes64, 0);
            ulong y = x & 0xFFF000;
            y = y >> 12;                       
            return (ushort)y;
        }

        set
        {
            byte[] bytes64 = new byte[8];
            Array.Copy(data, bytes64, data.Length);
            ulong x = BitConverter.ToUInt64(bytes64, 0);
            x = x & ~((ulong)0xFFF000);

            ulong y = (ulong)(value << 12) & 0xFFF000;                    
            ulong res = x | y;
            bytes64 = BitConverter.GetBytes(res);
            Array.Copy(bytes64, data, data.Length);
        }
    }


}

Content is retrieved from StackExchange API.

Auto-generated by ruso-archive tools.

Back to top Stack Overflow answers (published from sources in GitHub repository). Copyright (c) 2020, MSDN.WhiteKnight. Content licensed under BSD 3-Clause License.
Generated by DocFX