如何将C嵌套结构/并集转换为C#



我正在尝试编写一个测试应用程序来解组二进制blob。blob是由一个低级的h/w接口生成的。基于c头,我发现二进制blob是这样定义的,

typedef struct Report
{
uint32_t SnpVersion;
uint32_t SnpGuestSvn;
union {
uint64_t ModelVer_t;
struct {
uint64_t AbiMinor:8;
uint64_t AbiMajor:8;
uint64_t TTAllowed:1;
uint64_t RrvdTrue:1;
uint64_t MigrateTTAllowed:1;
uint64_t DebugAllowed:1;
uint64_t RrvdFalse:44;
} TuneConfig;
} TunePolicy;
union {
uint64_t Asuint64_t;
struct {
uint64_t TTEnabled:1;
uint64_t RRvd:63;
} ChannelConfig;
} ChannelPolicy;
uint8_t  PolicyDigest[48];
}

我需要对c#中的二进制blob进行解组。基于该链接处的ref,https://learn.microsoft.com/en-us/dotnet/framework/interop/marshalling-classes-structures-and-unions,我应该能够生成它。但是,我仍然不确定表示AbiMinor:8的语法;托管代码中的保留位。

表示保留位的方法是通过应用于struct字段的[StructLayout][FieldOffset]属性。然而这个并集有几个小于一个字节的字段,所以我建议不要这样做,因为[FieldOffset]是以整个字节为单位的,所以尝试复制这个并集不会给自己带来任何好处。

如果您要封送一个结构,那么只需使用适当大小的基元并编写代码即可获取底层值。

[StructLayout(LayoutKind.Sequential)]
public struct ReportManaged
{
// the actual fields of the struct
private readonly uint SnpVersion;
private readonly uint SnpGuestSvn;
private readonly ulong TunePolicyUnion;
private readonly ulong ChannelPolicyUnion;
private fixed byte[48] PolicyDigest;
// properties to access the struct's data
public ulong ModelVer => TunePolicy;

public byte TuneConfig_AbiMinor => //most significant byte of TunePolicyUnion
public byte TuneConfig_AbiMajor => //2nd most significant byte of TunePolicyUnion
public bool TuneConfig_TTAllowed => //17th bit of TunePolicyUnion
public bool TuneConfig_RvrdTrue => //18th bit of TunePolicyUnion
public bool TuneConfig_MigrateTTAllowed => //19th bit of TunePolicyUnion
public bool TuneConfig_DebugAllowed => //20th bit of TunePolicyUnion
public bool TuneConfig_RrvdFalse => //rest of TunePolicyUnion
public ulong ChannelPolicy_AsUInt64 => ChannelPolicyUnion;

public bool ChannelConfig_TTEnabled => //most significant byte of ChannelPolicyUnion
public ulong ChannelConfig_RRvd => //rest of ChannelPolicyUnion
}

另一个选项,也是我自己喜欢使用的选项,是将Report简单地封送为一个字节数组,然后像读取流一样读取它,在进行过程中构建一个C#对象。联合定义了一种消息格式。每个消息以32位SnpVersion和32位Snp GuestSvn开始,然后它有一个64位Model Version或Tune Config,然后是一个64比特字段或ChannelConfig,它总是以48字节的数据结束。

最新更新