亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

C#中的位字段

C#中的位字段

C#
慕村9548890 2019-10-08 10:53:21
我有一個需要填充并寫入磁盤的結構(實際上有幾個)。一個例子是:byte-6    bit0 - original_or_copy  bit1 - copyright  bit2 - data_alignment_indicator  bit3 - PES_priority  bit4-bit5 - PES_scrambling control.  bit6-bit7 - reserved  在CI中可能會執行以下操作:struct PESHeader  {    unsigned reserved:2;    unsigned scrambling_control:2;    unsigned priority:1;    unsigned data_alignment_indicator:1;    unsigned copyright:1;    unsigned original_or_copy:1;};有什么方法可以在C#中執行此操作,從而使我能夠使用結構取消引用點運算符訪問這些位?對于兩個結構,我只需要包裝訪問器函數中的位移即可。我有大量的結構要以這種方式處理,因此我正在尋找更易于閱讀和編寫的東西。
查看完整描述

3 回答

?
拉莫斯之舞

TA貢獻1820條經驗 獲得超10個贊

我可能會使用屬性將某些東西組合在一起,然后使用一個轉換類將適當地歸因于結構的結構轉換為位域基元。就像是...


using System;


namespace BitfieldTest

{

    [global::System.AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]

    sealed class BitfieldLengthAttribute : Attribute

    {

        uint length;


        public BitfieldLengthAttribute(uint length)

        {

            this.length = length;

        }


        public uint Length { get { return length; } }

    }


    static class PrimitiveConversion

    {

        public static long ToLong<T>(T t) where T : struct

        {

            long r = 0;

            int offset = 0;


            // For every field suitably attributed with a BitfieldLength

            foreach (System.Reflection.FieldInfo f in t.GetType().GetFields())

            {

                object[] attrs = f.GetCustomAttributes(typeof(BitfieldLengthAttribute), false);

                if (attrs.Length == 1)

                {

                    uint fieldLength  = ((BitfieldLengthAttribute)attrs[0]).Length;


                    // Calculate a bitmask of the desired length

                    long mask = 0;

                    for (int i = 0; i < fieldLength; i++)

                        mask |= 1 << i;


                    r |= ((UInt32)f.GetValue(t) & mask) << offset;


                    offset += (int)fieldLength;

                }

            }


            return r;

        }

    }


    struct PESHeader

    {

        [BitfieldLength(2)]

        public uint reserved;

        [BitfieldLength(2)]

        public uint scrambling_control;

        [BitfieldLength(1)]

        public uint priority;

        [BitfieldLength(1)]

        public uint data_alignment_indicator;

        [BitfieldLength(1)]

        public uint copyright;

        [BitfieldLength(1)]

        public uint original_or_copy;

    };


    public class MainClass

    {

        public static void Main(string[] args)

        {

            PESHeader p = new PESHeader();


            p.reserved = 3;

            p.scrambling_control = 2;

            p.data_alignment_indicator = 1;


            long l = PrimitiveConversion.ToLong(p);



            for (int i = 63; i >= 0; i--)

            {

                Console.Write( ((l & (1l << i)) > 0) ? "1" : "0");

            }


            Console.WriteLine();


            return;

        }

    }

}

產生預期的... 000101011。當然,它需要更多的錯誤檢查和更精巧的鍵入,但是(我認為)該概念是合理的,可重用的,并且可以讓您輕松打出一打維護的結構。

查看完整回答
反對 回復 2019-10-08
?
紅顏莎娜

TA貢獻1842條經驗 獲得超13個贊

通過使用枚舉,您可以執行此操作,但是看起來很尷尬。


[Flags]

public enum PESHeaderFlags

{

    IsCopy = 1, // implied that if not present, then it is an original

    IsCopyrighted = 2,

    IsDataAligned = 4,

    Priority = 8,

    ScramblingControlType1 = 0,

    ScramblingControlType2 = 16,

    ScramblingControlType3 = 32,

    ScramblingControlType4 = 16+32,

    ScramblingControlFlags = ScramblingControlType1 | ScramblingControlType2 | ... ype4

    etc.

}


查看完整回答
反對 回復 2019-10-08
?
千巷貓影

TA貢獻1829條經驗 獲得超7個贊

您想要StructLayoutAttribute


[StructLayout(LayoutKind.Explicit, Size=1, CharSet=CharSet.Ansi)]

public struct Foo 

{ [FieldOffset(0)]public byte original_or_copy; 

  [FieldOffset(0)]public byte copyright;

  [FieldOffset(0)]public byte data_alignment_indicator; 

  [FieldOffset(0)]public byte PES_priority; 

  [FieldOffset(0)]public byte PES_scrambling_control; 

  [FieldOffset(0)]public byte reserved; 

}

這實際上是一個并集,但您可以將其用作位域-您只需要知道每個字段的位應該在字節中的哪個位置即可。實用程序函數和/或與AND相對的常量會有所幫助。


const byte _original_or_copy = 1;

const byte _copyright        = 2;


//bool ooo = foo.original_or_copy();

static bool original_or_copy(this Foo foo) 

{ return  (foo.original_or_copy & _original_or_copy)  == original_or_copy;

}    

還有LayoutKind.Sequential,它可以讓您以C方式進行操作。


查看完整回答
反對 回復 2019-10-08
  • 3 回答
  • 0 關注
  • 501 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號