如何在C#中编组包含DWORD位域的C ++结构

时间:2015-01-30 19:22:43

标签: c# c struct marshalling bit-fields

我正在使用非托管SDK并且有一个我需要在C#编组的结构:

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

我已经四处寻找并试过了很多东西,但似乎无法弄明白。这是我阅读大量帖子后的最新尝试:

    [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); }
        }
    }

这个结构是SDK调用的一部分,它包含其他结构等等。长话短说,我不是百分之百确定这是否是错误的,是什么导致调用无法正常工作。我从来没有处理过像这样的结构,所以我认为这是最可能的原因。如果这看起来是正确的,请告诉我,我将发布更多其他代码。一开始就试着保持简约。

更新

感谢@Ben Voigt指出我正确的方向。以下是供将来参考的正确代码:

[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; }
    }
}

1 个答案:

答案 0 :(得分:3)

整个结构中只有一个32位整数。所有各种组件都被打包到32位结构的不同子集中。

您可能希望在.NET端只使用一个UInt32字段,以及访问各个组件的属性。 .NET BitVector32类可以帮助您提取和更新单个32位字段中的位域。