1

I'm working with an unmanaged SDK and have a struct that I am needing to marshal in C#:

struct DEV_TIME
{
    DWORD  second:6;
    DWORD  minute:6;
    DWORD  hour:5;
    DWORD  day:5;
    DWORD  month:4;
    DWORD  year:6;
}

I've searched around and have tried a number of things but can't seem to figure it out. Here is my latest attempt after reading numerous posts:

    [StructLayout(LayoutKind.Sequential)]
    public struct DHDEVTIME
    {
        internal uint secData;
        internal uint minData;
        internal uint hourData;
        internal uint dayData;
        internal uint monData;
        internal uint yearData;

        public uint second
        {
            get { return secData & 0x3F; }
            set { secData = (secData % ~0x3Fu) | (value & 0x3F); }
        }

        public uint minute
        {
            get { return minData & 0x3F; }
            set { minData = (minData % ~0x3Fu) | (value & 0x3F); }
        }

        public uint hour
        {
            get { return hourData & 0x1F; }
            set { hourData = (hourData % ~0x1Fu) | (value & 0x1F); }
        }

        public uint day
        {
            get { return dayData & 0x1F; }
            set { dayData = (dayData % ~0x1Fu) | (value & 0x1F); }
        }

        public uint month
        {
            get { return monData & 0xF; }
            set { monData = (monData % ~0xFu) | (value & 0xF); }
        }

        public uint year
        {
            get { return yearData & 0x3F; }
            set { yearData = (yearData % ~0x3Fu) | (value & 0x3F); }
        }
    }

This struct is part of a call to the SDK, which contains other structs, etc. etc. Long story short, I'm not 100% sure if this is even wrong and is what is causing the call to not work correctly. I've never had to deal with a struct like this, so I'm thinking this is the most likely cause. If this appears to be correct, let me know and I'll post some more of the other code. Just trying to be minimalistic at first.

UPDATE

Thanks to @Ben Voigt for pointing me in the right direction. Below is the correct code for future reference:

[StructLayout(LayoutKind.Sequential)]
public struct DHDEVTIME
{
    internal uint data;

    public uint second
    {
        get { return data & 0x3F; }
        set { data = (data & ~0x3Fu) | (value & 0x3F); }
    }

    public uint minute
    {
        get { return (data >> 6) &  0x3F; }
        set { data = (data & ~(0x3Fu << 6)) | (value & 0x3F) << 6; }
    }

    public uint hour
    {
        get { return (data >> 12) & 0x1F; }
        set { data = (data & ~(0x1Fu << 12)) | (value & 0x1F) << 12; }
    }

    public uint day
    {
        get { return (data >> 17) & 0x1F; }
        set { data = (data & ~(0x1Fu << 17)) | (value & 0x1F) << 17; }
    }

    public uint month
    {
        get { return (data >> 22) & 0xF; }
        set { data = (data & ~(0xFu << 22)) | (value & 0xF) << 22; }
    }

    public uint year
    {
        get { return (data >> 26) & 0x3F; }
        set { data = (data & ~(0x3Fu << 26)) | (value & 0x3F) << 26; }
    }
}
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
Brian
  • 819
  • 4
  • 20
  • 35

1 Answers1

3

There's only ONE 32-bit integer in that entire structure. All the various components are packed into different subsets of the 32-bit structure.

You'll probably want to use exactly one UInt32 field on the .NET side, and properties for access to the individual components. The .NET BitVector32 class can help you with extracting and updating the bitfields within the single 32-bit field.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • IIRC how is this actually stored is implementation defined . – AK_ Jan 30 '15 at 19:52
  • @AK: yes and no. Implementations are required to fit all the bit fields in one DWORD. The order within that is not standard, however. – Ben Voigt Jan 30 '15 at 19:54
  • @ Ben Vigt... Thanks for pointing that out. Looking at the struct definition, was unsure if it was a 6 separate DWORDS only utilizing x number of bits, or if it was 1 DWORD separated in 6 'pieces'. Thanks for the info. – Brian Jan 30 '15 at 20:32
  • Just an FYI, the following is an answer to another question that assisted me with the code: http://stackoverflow.com/a/11145067/469194 – Brian Jan 30 '15 at 20:34