【问题标题】:Is there a better way to rewrite this structure where I have to get a few bits from c++ to c#?有没有更好的方法来重写这个结构,我必须从 c++ 到 c# 获取一些位?
【发布时间】:2021-03-03 08:28:54
【问题描述】:

将结构从 c++ 重写为 c#。我正在寻找使我的代码透明的最佳解决方案。目前,我必须通过 bool 数组来获取例如的值。 4 位。

C++ 代码:

uint16_t afc :4;
uint16_t prp :3;
uint16_t prs :3;
uint16_t q101 :3;
uint16_t ez1 :1;
uint16_t cw :1; 
uint16_t wa_kb :1;

我的 C# 代码:

[Flags]
public enum MainScr_Enum : ushort
{
    None = 0,
    afc_1 = 1 << 0,
    afc_2 = 1 << 1,
    afc_3 = 1 << 2,
    afc_4 = 1 << 3,
    prp_1 = 1 << 4,
    prp_2 = 1 << 5,
    prp_3 = 1 << 6,
    prs_1 = 1 << 7,
    prs_2 = 1 << 8,
    prs_3 = 1 << 9,
    q101_1 = 1 << 10,
    q101_2 = 1 << 11,
    q101_3 = 1 << 12,
    ez1 = 1 << 13,
    cw = 1 << 14,
    wa_kb = 1 << 15,
}

而且我必须使用这种方法来获取价值:

var val = GetValueFromFlags(new bool[] {MainScr_Enum.HasFlag(MainScr_Enum.afc_1), MainScr_Enum.HasFlag(MainScr_Enum.afc_2), MainScr_Enum.HasFlag(MainScr_Enum.afc_3), MainScr_Enum.HasFlag(MainScr_Enum.afc_4),})

public int GetValueFromFlags(bool[] list)
{
    int value = 0;
    for (int i = 0; i < list.Length; i++)
    {
        value += Convert.ToInt32(list[i]) << i;
    }
    return value;
}

我从不需要单独的 afc_1 e.t.c 值。

编辑(测试程序):

class Program
{
    static void Main(string[] args)
    {
        Flags flags = new Flags();
        var array = new byte[] { 2, 1, 1, 1 };
        flags.FromArray(array);
        var test = (int)flags.MainScr_Enum;
        flags.MainScr_Enum.HasFlag(MainScr_Enum.afc_1);
    }
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class Flags
{
    public ushort TickTimer; 
    public MainScr_Enum MainScr_Enum;      
    public void FromArray(byte[] val)
    {
        int size = Marshal.SizeOf(this);
        IntPtr ptr = Marshal.AllocHGlobal(size);
        Marshal.Copy(val, 0, ptr, size);
        Marshal.PtrToStructure(ptr, this);
        Marshal.FreeHGlobal(ptr);
    }
}
[Flags]
public enum MainScr_Enum : ushort
{
    None = 0,
    afc_1 = 1 << 0,
    afc_2 = 1 << 1,
    afc_3 = 1 << 2,
    afc_4 = 1 << 3,
    prp_1 = 1 << 4,
    prp_2 = 1 << 5,
    prp_3 = 1 << 6,
    prs_1 = 1 << 7,
    prs_2 = 1 << 8,
    prs_3 = 1 << 9,
    q101_1 = 1 << 10,
    q101_2 = 1 << 11,
    q101_3 = 1 << 12,
    ez1 = 1 << 13,
    cw = 1 << 14,
    wa_kb = 1 << 15,
}

【问题讨论】:

  • 您的要求不是很清楚。你想提高可读性吗?表现?你使用这个的上下文是什么?
  • @JonasH 我希望代码更干净。现在要获得 4 位的值,我必须创建数组并使用 GetValueFromFlags () 方法,这似乎不可读。我的程序中有很多结构,现在我必须为每个值都这样做。此外,如果我想在其他地方获得这个值,我必须再做一次。

标签: c# c++ structure


【解决方案1】:

创建一个类并将这些变量声明为这样的成员并使用。

ushort afc = 4;
ushort prp = 3;
ushort prs = 3;
ushort q101 = 3;
ushort ez1 = 1;
ushort cw = 1;
ushort wa_kb = 1;

【讨论】:

  • 我是否理解如果我以这种方式创建一个结构,然后用 Marshal 从 4 个字节重写结构后,我会将值重写到这些 ushorts 中?
  • 它不起作用。结构尺寸增加
【解决方案2】:

如果您想组合来自Flags 枚举的各种值,您可以像这样将这些值组合在一起:

var val = MainScr_Enum.afc_1 | MainScr_Enum.afc_2 | MainScr_Enum.afc_3 | MainScr_Enum.afc_4;

不需要单独的数组之类的。

在这种情况下,val 将是 MainScr_Enum 类型。如果您希望它是 int,您可以直接转换:

int val = (int)(MainScr_Enum.afc_1 | MainScr_Enum.afc_2 | MainScr_Enum.afc_3 | MainScr_Enum.afc_4);

【讨论】:

  • 我犯了一个错误,我不能像这样从这个标志中获取价值: MainScr_Enum.afc_1 我必须这样做: MainScr_Enum.HasFlag(MainScr_Enum.afc_1) 当我用这个“|”取值时我得到 bool 并且不能将它投射到 int 上。
  • 为什么一定要用HasFlag()
  • 我添加了程序,你可以在哪里测试它。没有 MainScr_Enum.afc_1 属性。我只能转换 (int)MainScr_Enum 并获得完整的标志值。
  • 啊,所以你有一个int,你想把它变成MainScr_Enum值的集合,对吗?
  • 我从字节数组创建结构。在我看来,将值分解为 4 位,然后使用上述方法提取值并不是最优的。与以下情况一样:afc。我正在寻找更优化的解决方案。
猜你喜欢
  • 1970-01-01
  • 2020-03-14
  • 2020-03-18
  • 1970-01-01
  • 2014-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多