Mashalling strange structs

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • wtfxxx@gmail.com

    Mashalling strange structs

    Hi,

    How would I marshall this struct in C#? Thanks in advance:

    typedef struct
    {
    ULONG bConnected :1;
    ULONG bPnPEnabled :1;
    ULONG bEnabled :1;
    ULONG :1;
    ULONG ConnectionState :6;
    } PNP_STATUS;

  • Jeroen Mostert

    #2
    Re: Mashalling strange structs

    wtfxxx@gmail.co m wrote:
    How would I marshall this struct in C#? Thanks in advance:
    >
    typedef struct
    {
    ULONG bConnected :1;
    ULONG bPnPEnabled :1;
    ULONG bEnabled :1;
    ULONG :1;
    ULONG ConnectionState :6;
    } PNP_STATUS;
    >
    Those are bitfields, for which C# has no native support. You can emulate
    them with properties, though:

    [StructLayout(La youtKind.Sequen tial, Size = 4)]
    struct PNP_STATUS {
    private ushort s;

    private bool getBit(int bit) {
    return (s & (1 << bit)) != 0;
    }

    private void setBit(int bit, bool value) {
    if (value) {
    s |= (ushort) (1 << bit);
    } else {
    s &= (ushort) ~(1 << bit);
    }
    }

    private int getIntSection(i nt startBit, int count) {
    return (s >startBit) & ((1 << count) - 1);
    }

    private void setIntSection(i nt startBit, int count, int value) {
    s |= (ushort) ((value & (1 << count) - 1) << startBit);
    }

    public bool bConnected {
    get { return getBit(0); }
    set { setBit(0, value); }
    }

    public bool bPnPEnabled {
    get { return getBit(1); }
    set { setBit(1, value); }
    }

    public bool bEnabled {
    get { return getBit(2); }
    set { setBit(2, value); }
    }

    public int ConnectionState {
    get { return getIntSection(4 , 6); }
    set { setIntSection(4 , 6, value); }
    }
    }

    The "Size = 4" above forces aligning to a 4-byte boundary, which is probably
    what the unmanaged side expects/wants too. You may need to change this, however.

    --
    J.

    Comment

    • wtfxxx@gmail.com

      #3
      Re: Mashalling strange structs

      On Jun 11, 2:10 pm, Jeroen Mostert <jmost...@xs4al l.nlwrote:
      wtf...@gmail.co m wrote:
      How would I marshall this struct in C#? Thanks in advance:
      >
      typedef struct
      {
      ULONG bConnected :1;
      ULONG bPnPEnabled :1;
      ULONG bEnabled :1;
      ULONG :1;
      ULONG ConnectionState :6;
      } PNP_STATUS;
      >
      Those are bitfields, for which C# has no native support. You can emulate
      them with properties, though:
      >
      [StructLayout(La youtKind.Sequen tial, Size = 4)]
      struct PNP_STATUS {
      private ushort s;
      >
      private bool getBit(int bit) {
      return (s & (1 << bit)) != 0;
      }
      >
      private void setBit(int bit, bool value) {
      if (value) {
      s |= (ushort) (1 << bit);
      } else {
      s &= (ushort) ~(1 << bit);
      }
      }
      >
      private int getIntSection(i nt startBit, int count) {
      return (s >startBit) & ((1 << count) - 1);
      }
      >
      private void setIntSection(i nt startBit, int count, int value) {
      s |= (ushort) ((value & (1 << count) - 1) << startBit);
      }
      >
      public bool bConnected {
      get { return getBit(0); }
      set { setBit(0, value); }
      }
      >
      public bool bPnPEnabled {
      get { return getBit(1); }
      set { setBit(1, value); }
      }
      >
      public bool bEnabled {
      get { return getBit(2); }
      set { setBit(2, value); }
      }
      >
      public int ConnectionState {
      get { return getIntSection(4 , 6); }
      set { setIntSection(4 , 6, value); }
      }
      }
      >
      The "Size = 4" above forces aligning to a 4-byte boundary, which is probably
      what the unmanaged side expects/wants too. You may need to change this, however.
      >
      --
      J.http://symbolsprose.blogspot.com
      Thanks J, I didnt know what that struct was called or doing. This
      cleared up a lot of questions.

      Comment

      • Pavel Minaev

        #4
        Re: Mashalling strange structs

        On Jun 11, 8:10 pm, wtf...@gmail.co m wrote:
        Hi,
        >
        How would I marshall this struct in C#? Thanks in advance:
        >
        typedef struct
        {
        ULONG bConnected :1;
        ULONG bPnPEnabled :1;
        ULONG bEnabled :1;
        ULONG :1;
        ULONG ConnectionState :6;
        >
        } PNP_STATUS;
        You might also want to have a look at BitVector32 struct. It
        encapsulates a 32-bit int (as the name implies), and allows you to
        "slice" it into chunks of several bits using the CreateSection method,
        and then access them individually. For your case, it would be
        something like this:

        struct PNP_STATUS
        {
        public static readonly BitVector32.Sec tion
        bConnected = BitVector32.Cre ateSection(1), // 1 bit at the
        beginning
        bPnPEnabled = BitVector32.Cre ateSection(1, bConnected), // 1 bit
        following bConnected
        bEnabled = BitVector32.Cre ateSection(1, bPnPEnabled), // 1 bit
        following bPnPEnabled
        padding = BitVector32.Cre ateSection(1, bEnabled ), // 1 bit
        following bEnabled
        ConnectionState = BitVector32.Cre ateSection(1, padding); // 6 bits
        following padding

        public BitVector32 Data;
        }

        Then you can access it like this:

        PNP_STATUS status;
        if (status[PNP_STATUS.bCon nected] == 1)
        {
        status[PNP_STATUS.Conn ectionState]++;
        }

        When you have do deal with a large number of bitfields, this makes it
        a little bit more obvious. Of course, it is still better to hide all
        those Section objects inside the struct as private fields, and expose
        them via properties.

        Comment

        Working...