首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何用位字段从C++结构中提取值

如何用位字段从C++结构中提取值
EN

Stack Overflow用户
提问于 2014-07-16 21:39:27
回答 4查看 2.3K关注 0票数 2

这是我的问题,我有一个结构(我不能改变)如下:

代码语言:javascript
运行
复制
struct X
{
    uint8_t fieldAB;
    uint8_t fieldCDE;
    uint8_t fieldFGH;
    ...
}

该结构的每个字段都包含使用位掩码(位域)打包的不同值,例如,fieldAB在hi/lo小口中包含两个不同的值(A和B),而fieldCDE包含三个不同的值(C、D和E,具有以下位掩码:位7-6、位5-4-3、位2-1-0)等等。

我想编写一个简单的API来使用enum读写这个值,这样可以轻松地访问每个字段的值:

代码语言:javascript
运行
复制
getValue(valueTypeEnum typeOfValue, X & data);
setValue(valueTypeEnum typeOfValue, X & data, uint8_t value);

其中枚举valueTypeEnum是这样的:

代码语言:javascript
运行
复制
enum valueTypeEnum
{
    A,
    B,
    C,
    D,
    E,
    ...
}

我的想法是使用一个映射(字典),如果valueTypeEnum返回要使用的位掩码和访问结构的正确字段的偏移量,但我认为它有点棘手,而且不太优雅。你有什么建议?

EN

回答 4

Stack Overflow用户

发布于 2014-07-16 21:57:12

我可以想到几种方法,最简单的方法是直接在结构中使用位字段:

代码语言:javascript
运行
复制
struct X {
   uint32_t A : 4; // 4 bits for A. 
   uint32_t B : 4; 
   uint32_t C : 4; 
   uint32_t D : 4; 
   uint8_t E : 7; 
   uint8_t F : 1;
};

然后,您可以很容易地获取或设置值,例如:

代码语言:javascript
运行
复制
X x;
x.A = 0xF;

另一种方法可能是直接将其编码到宏或内联函数中,但我想您要查找的可能是位字段。

正如注释中指出的那样,位字段的实际行为可能取决于您的平台,因此,如果空间是最重要的,您应该检查它是否符合您的预期。也请看这里以获取C++中有关位字段的更多信息.

票数 1
EN

Stack Overflow用户

发布于 2014-07-17 08:12:15

我会再深入一些:

您的X结构保持不变:

代码语言:javascript
运行
复制
struct X
{
    uint8_t fieldAB;
    uint8_t fieldCDE;
    uint8_t fieldFGH;
};

为了便于翻译,让我们定义一个联合:

代码语言:javascript
运行
复制
union Xunion {
    X x;
    struct Fields { // Named in case you need to sizeof() it
        uint8_t A   : 4;
        uint8_t B   : 4;

        uint8_t C   : 2;
        uint8_t D   : 3;
        uint8_t E   : 3;

        uint8_t F   : 2;
        uint8_t G   : 3;
        uint8_t H   : 3;
    };
};

现在您可以方便地访问这些位字段。

在有人试图剥我的皮之前,请注意,这绝不是可移植的,甚至是C++标准所定义的。但在任何正常的编译器上,它都能达到你的期望。

您可能需要在Fields结构中添加一个特定于编译器的打包指令(例如GCC的Fields),以及一个确保sizeof和工会成员严格相等的static_assert

票数 1
EN

Stack Overflow用户

发布于 2014-07-16 22:11:41

你最好的选择是忘记使用一个结构,或者如果是这样的话,使用一个结构和一个字节数组的结合。然后让您的访问函数使用字节数组,它很容易计算偏移量等等。这样做,我相信你一定会访问你想要的字节。

缺点是,您将不得不重新组装16位和32位值,如果有,在结构中找到,并在这样做时考虑到任何感兴趣的问题。如果您知道任何这样的值都是在16位或32位地址边界上找到的,您可以使用union‘short和long数组来完成这一任务,这可能是最好的,尽管有点不透明。

HTH

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24791253

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档