如何在 C# 中编组包含 DWORD 位域的 C++ 结构
How to marshal C++ struct containing DWORD bitfields in C#
我正在使用非托管 SDK,并且有一个结构需要在 C# 中编组:
struct DEV_TIME
{
DWORD second:6;
DWORD minute:6;
DWORD hour:5;
DWORD day:5;
DWORD month:4;
DWORD year:6;
}
我四处搜索并尝试了很多方法,但似乎无法弄清楚。这是我在阅读大量 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); }
}
}
这个结构是对 SDK 的调用的一部分,它包含其他结构等等。长话短说,我不能 100% 确定这是否是错误的,是什么导致调用不正常工作。我从来没有处理过这样的结构,所以我认为这是最可能的原因。如果这似乎是正确的,请告诉我,我将 post 提供更多其他代码。一开始只是想简约。
更新
感谢@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; }
}
}
整个结构中只有一个 32 位整数。所有不同的组件都被打包到 32 位结构的不同子集中。
您可能希望在 .NET 端只使用一个 UInt32
字段,以及用于访问各个组件的属性。 .NET BitVector32
class 可以帮助您提取和更新单个 32 位字段中的位字段。
我正在使用非托管 SDK,并且有一个结构需要在 C# 中编组:
struct DEV_TIME
{
DWORD second:6;
DWORD minute:6;
DWORD hour:5;
DWORD day:5;
DWORD month:4;
DWORD year:6;
}
我四处搜索并尝试了很多方法,但似乎无法弄清楚。这是我在阅读大量 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); }
}
}
这个结构是对 SDK 的调用的一部分,它包含其他结构等等。长话短说,我不能 100% 确定这是否是错误的,是什么导致调用不正常工作。我从来没有处理过这样的结构,所以我认为这是最可能的原因。如果这似乎是正确的,请告诉我,我将 post 提供更多其他代码。一开始只是想简约。
更新
感谢@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; }
}
}
整个结构中只有一个 32 位整数。所有不同的组件都被打包到 32 位结构的不同子集中。
您可能希望在 .NET 端只使用一个 UInt32
字段,以及用于访问各个组件的属性。 .NET BitVector32
class 可以帮助您提取和更新单个 32 位字段中的位字段。