C# 中使用位字段编组结构
是否可以将包含位字段的 C 风格结构封送到 C# 结构,或者必须将其封送到基本类型,然后执行位掩码?
例如,我想从这样的 C 风格结构中进行编组:
struct rgb16 {
unsigned int R : 4;
unsigned int G : 5;
unsigned int B : 4;
}
并将其编组到如下所示的内容上:
[StructLayout(LayoutKind.Sequential)]
public struct Rgb16 {
public byte R;
public byte G;
public byte B;
}
Is it possible to marshal a C-style struct containing bit-fields to a C# struct, or would you have to marshal it to a basic type and then do bit-masks?
E.g. I would like to marshal from a C style structure like this:
struct rgb16 {
unsigned int R : 4;
unsigned int G : 5;
unsigned int B : 4;
}
And marshal it onto something like this:
[StructLayout(LayoutKind.Sequential)]
public struct Rgb16 {
public byte R;
public byte G;
public byte B;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
C# 中没有位域。所以我会选择封装位摆弄的属性:
我避免添加设置器,因为我喜欢不可变的结构,但原则上你也可以添加它们。
There are no bit-fields in C#. So I'd go with properties that encapsulate the bit fiddling:
I've avoided adding setters, because I like immutable structs, but in principle you can add them too.
这是我的 rgb16 结构的“安全 c#”端口。
Thats my "safe c#" port of a rgb16 struct.
我昨天花了大部分时间试图解决这个问题,作为“使用 c# 的 StrucLayout 和 FieldOffset 表示联合位域”问题的一个更大的部分,它不仅会回答您的问题(上面),而且可以在这里找到:
使用 C# 的 StrucLayout 和 FieldOffset 表示联合位域
本质上,您需要定义一个结构(值类型)并使用 BitVector32对象来定义您想要表示的每个位域的位域部分。您可以跳过有关工会的部分,因为这与您的问题无关,但帖子的大部分内容仍然与您的问题有关。
只是为了好玩,我想我会为您的 RGB16 示例创建 C# 结构:
注意:BitVector32 对象的长度为 32 位,因此名称上的“16”有点误导......请请注意这一点
要使用它,您将按如下方式分配:
另外,请注意,有对此的引用:
C# 中的位字段
这里还有很多其他答案,但它们有很多陷阱需要注意。也许我在这里能做的最好的事情就是列出您可能想要查找的内容:
I spent the better part of yesterday trying to solve this problem as a bigger part of the issue of "Representing union bitfields using c#'s StrucLayout and FieldOffset", which will not only answer you question (above), but can be found here:
Representing union bitfields using c#'s StrucLayout and FieldOffset
Essentially, you will need to define a struct (a value type) and use the BitVector32 object to define the bitfield section for each bitfield you wish to represent. You can skip the part about the union since that does not pertain to your question, but the large majority of the post still pertains to your question.
Just for the fun of it, I thought I would whip up the C# struct for your RGB16 example:
Note: BitVector32 object are 32 bits in length, so the '16' on the moniker is kind of misleading... please take note of that
To use this, you would allocate as follows:
Also, please note that there is a reference to this:
Bit fields in C#
There are many other answers here, but they have many pitfalls to be aware of. Perhaps the best thing I can do here is just list what you might want to look for:
我已经整理了如下位域:
其中属性通过将值除以位来创建新的结构,就像您提到的那样。
这不是最好的方法,但还没有找到其他对我有用的方法。
如果您愿意,我可以提供 GetBitField 的代码(它不是很紧凑)
更新:托尼在您的问题的评论中提供的链接使用相同的想法,但似乎比我的更准确,所以如果你找不到更好的解决方案,请使用他的解决方案
I've marshaled bitfields like:
where the property creates new structure like you mentioned by dividing Value to bits.
Aren't the best way to do that, but haven't found anything else that worked for me.
I can provide the code for GetBitField if you want (it isn't very compact)
Upd: The link provided by Tony in the comments to your question uses the same idea but seems more accurate then mine, so use his solution if you cannot find any better