gpt4 book ai didi

c# - C# 中的位域

转载 作者:太空宇宙 更新时间:2023-11-03 15:00:47 26 4
gpt4 key购买 nike

我有一个结构需要填充并写入磁盘(实际上是几个)。

一个例子是:

byte-6    
bit0 - original_or_copy
bit1 - copyright
bit2 - data_alignment_indicator
bit3 - PES_priority
bit4-bit5 - PES_scrambling control.
bit6-bit7 - reserved

在 C 中我可能会做如下的事情:

struct PESHeader  {
unsigned reserved:2;
unsigned scrambling_control:2;
unsigned priority:1;
unsigned data_alignment_indicator:1;
unsigned copyright:1;
unsigned original_or_copy:1;
};

有什么方法可以在 C# 中执行此操作,使我能够使用结构取消引用点运算符访问这些位?

对于一些结构,我可以在访问器函数中进行移位。

我有大量的结构需要以这种方式处理,所以我正在寻找更容易阅读和更快编写的东西。

最佳答案

我可能会使用属性组合一些东西,然后是一个转换类,将适当的属性结构转换为位域基元。像...

using System;

namespace BitfieldTest
{
[global::System.AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
sealed class BitfieldLengthAttribute : Attribute
{
uint length;

public BitfieldLengthAttribute(uint length)
{
this.length = length;
}

public uint Length { get { return length; } }
}

static class PrimitiveConversion
{
public static long ToLong<T>(T t) where T : struct
{
long r = 0;
int offset = 0;

// For every field suitably attributed with a BitfieldLength
foreach (System.Reflection.FieldInfo f in t.GetType().GetFields())
{
object[] attrs = f.GetCustomAttributes(typeof(BitfieldLengthAttribute), false);
if (attrs.Length == 1)
{
uint fieldLength = ((BitfieldLengthAttribute)attrs[0]).Length;

// Calculate a bitmask of the desired length
long mask = 0;
for (int i = 0; i < fieldLength; i++)
mask |= 1 << i;

r |= ((UInt32)f.GetValue(t) & mask) << offset;

offset += (int)fieldLength;
}
}

return r;
}
}

struct PESHeader
{
[BitfieldLength(2)]
public uint reserved;
[BitfieldLength(2)]
public uint scrambling_control;
[BitfieldLength(1)]
public uint priority;
[BitfieldLength(1)]
public uint data_alignment_indicator;
[BitfieldLength(1)]
public uint copyright;
[BitfieldLength(1)]
public uint original_or_copy;
};

public class MainClass
{
public static void Main(string[] args)
{
PESHeader p = new PESHeader();

p.reserved = 3;
p.scrambling_control = 2;
p.data_alignment_indicator = 1;

long l = PrimitiveConversion.ToLong(p);


for (int i = 63; i >= 0; i--)
{
Console.Write( ((l & (1l << i)) > 0) ? "1" : "0");
}

Console.WriteLine();

return;
}
}
}

这会产生预期的 ...000101011。当然,它需要更多的错误检查和稍微更理智的打字,但这个概念(我认为)是合理的、可重用的,并且可以让你敲出许多易于维护的结构。

亚当

关于c# - C# 中的位域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46294984/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com