qt 到 c# : 运算符在结构中意味着什么

发布于 2024-10-22 02:15:41 字数 384 浏览 4 评论 0原文

我有一段代码试图从旧的 qt 文件转换为 C#,但我有点不清楚下面的联合内的结构中发生了什么。我不确定“:”的作用...我猜它设置了大小,但找不到任何相关文档。另外,由于 C# 没有联合,转换此类内容的最佳实践是什么。谢谢

union uAWord
{
   uAWord()
     : m_AWord(0) {}

    struct sBcdAWord
    {
      quint32 m_O  :8;
      quint32 m_S  :2;
      quint32 m_D  :18;
      quint32 m_SS :3;
      quint32 m_P  :1;
    }
    sBcdAWord m_F;
    quint32 m_AWord;
}

I have a block of code that i'm trying to covert from an old qt file into C# but i'm a little unclear what is going on in the struct within the union below. I'm not sure what the ':' does... i'm guessing it sets the size but could not find any documentation on this. Also since C# does not have unions what is the best practice for converting something like this. Thank you

union uAWord
{
   uAWord()
     : m_AWord(0) {}

    struct sBcdAWord
    {
      quint32 m_O  :8;
      quint32 m_S  :2;
      quint32 m_D  :18;
      quint32 m_SS :3;
      quint32 m_P  :1;
    }
    sBcdAWord m_F;
    quint32 m_AWord;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

无敌元气妹 2024-10-29 02:15:41

这就是所谓的位字段。 sBcdWord 部分是一个 32 位字,每个字段是该字的一部分,分别占用 8,2,18,3,1 BIT
因此字布局如下:

  • Bit0-Bit7 m_0
  • Bit8-Bit9 m_S
  • Bit10-Bit27 m_D
  • Bit28-Bit30 m_ss
  • Bit31 m_P

如何在 C# 中移植它取决于您是否要持续移植代码,或者是否需要 PInvoke。对于 PInvoke,最好的解决方案可能是将 sBcdAWord 映射为 Unit32,并创建一些访问器策略来屏蔽读写。如果是代码端口,除非有特殊需要节省内存使用,否则使用分离的属性会很好。

This is what is called BitFields. the portion sBcdWord is a 32 bit word, and each field is a portion of that word taking respectively 8,2,18,3,1 BIT:
So the word layout is as below:

  • Bit0-Bit7 m_0
  • Bit8-Bit9 m_S
  • Bit10-Bit27 m_D
  • Bit28-Bit30 m_ss
  • Bit31 m_P

How to port this in C# depends if you are convettually porting the code, or if you need to PInvoke. In the case of PInvoke the best solution is probably to map sBcdAWord as an Unit32, and create some accessor strategy to mask on reading writing. If it is a code port, use separeted properties would be good unless there is special needing in memory usage saving.

天赋异禀 2024-10-29 02:15:41

该语法用于声明位域。该数字是该值的位数。请参阅示例 http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=%2Fcom.ibm.vacpp6m.doc%2Flanguage%2Fref%2Fclrc03defbitf.htm

我猜想,到 C# 的良好转换取决于具体情况。只要您不太注重空间,我就会将所有需要的值并行保留在一个类中。

That syntax is used to declare bitfields. The number is the number of bits for that value. See for example http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=%2Fcom.ibm.vacpp6m.doc%2Flanguage%2Fref%2Fclrc03defbitf.htm

A good conversion to C# depends on the case I guess. As long as you are not too space-conscious, I'd just keep all needed values in parallel in a class.

她说她爱他 2024-10-29 02:15:41

这会将 m_aWord 初始化为 0

That initializes m_aWord to 0.

赴月观长安 2024-10-29 02:15:41

要回答您的另一个问题,在 C# 中,您可能需要一个结构,并且需要使用属性来从中获得类似联合的行为。

这个特定的示例可能有点像:

[StructLayout(LayoutKind.Explicit)]
struct uAWord {

    [FieldOffset(0)] 
    private uint theWord = 0;

    [FieldOffset(0)] 
    public int m_P;
    [FieldOffset(1)] 
    public int m_S;
    [FieldOffset(3)] 
    public int m_SS;
    [FieldOffset(7)] 
    public int m_O;
    [FieldOffset(18)] 
    public int m_D;

    public uAWord(uint theWord){
        this.theWord = theWord;
    }
}

LayoutKind.Explicit 指示您将告诉它在内存中的哪个位置映射每个字段,FieldOffset(int) 告诉它从哪一位开始每个字段上。 请参阅此内容以了解更多详细信息。通过在构造函数中设置 uint theWord 来分配此结构,然后每个其他属性都将访问从不同内存地址开始的块。

不幸的是,这实际上是不正确的。您需要使用属性并进行一些位掩码/移位才能使其正确。像这样:

struct uAWord {

    private uint theWord = 0;

    public int m_P {get {return (theWord & 0x01);}}
    public int m_S {get {return (theWord & 0x02) << 2;}}
    public int m_SS {get {return (theWord & 0x04) << 3;}}
    public int m_0 {get {return (theWord & 0x18) << 6;}}
}

To answer your other question, in C# you'd likely want a struct, and you'd need to use attributes to get union-like behavior out of it.

This particular example could be somewhat like:

[StructLayout(LayoutKind.Explicit)]
struct uAWord {

    [FieldOffset(0)] 
    private uint theWord = 0;

    [FieldOffset(0)] 
    public int m_P;
    [FieldOffset(1)] 
    public int m_S;
    [FieldOffset(3)] 
    public int m_SS;
    [FieldOffset(7)] 
    public int m_O;
    [FieldOffset(18)] 
    public int m_D;

    public uAWord(uint theWord){
        this.theWord = theWord;
    }
}

The LayoutKind.Explicit indicates you will tell it where in the memory to map each field and the FieldOffset(int) tells which bit to start each field on. See this for more details. You'd assign this struct by setting the uint theWord in the constructor, then each of the other properties would access a chunk starting at a different memory address.

Unfortunately, that actually isn't correct. You'll need to use properties and do some bitmasking/shifting to get it right. Like this:

struct uAWord {

    private uint theWord = 0;

    public int m_P {get {return (theWord & 0x01);}}
    public int m_S {get {return (theWord & 0x02) << 2;}}
    public int m_SS {get {return (theWord & 0x04) << 3;}}
    public int m_0 {get {return (theWord & 0x18) << 6;}}
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文