这是我的问题,我有一个结构(我不能改变)如下:
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读写这个值,这样可以轻松地访问每个字段的值:
getValue(valueTypeEnum typeOfValue, X & data);
setValue(valueTypeEnum typeOfValue, X & data, uint8_t value);
其中枚举valueTypeEnum是这样的:
enum valueTypeEnum
{
A,
B,
C,
D,
E,
...
}
我的想法是使用一个映射(字典),如果valueTypeEnum返回要使用的位掩码和访问结构的正确字段的偏移量,但我认为它有点棘手,而且不太优雅。你有什么建议?
发布于 2014-07-16 21:57:12
我可以想到几种方法,最简单的方法是直接在结构中使用位字段:
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;
};
然后,您可以很容易地获取或设置值,例如:
X x;
x.A = 0xF;
另一种方法可能是直接将其编码到宏或内联函数中,但我想您要查找的可能是位字段。
正如注释中指出的那样,位字段的实际行为可能取决于您的平台,因此,如果空间是最重要的,您应该检查它是否符合您的预期。也请看这里以获取C++中有关位字段的更多信息.
发布于 2014-07-17 08:12:15
我会再深入一些:
您的X结构保持不变:
struct X
{
uint8_t fieldAB;
uint8_t fieldCDE;
uint8_t fieldFGH;
};
为了便于翻译,让我们定义一个联合:
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
。
发布于 2014-07-16 22:11:41
你最好的选择是忘记使用一个结构,或者如果是这样的话,使用一个结构和一个字节数组的结合。然后让您的访问函数使用字节数组,它很容易计算偏移量等等。这样做,我相信你一定会访问你想要的字节。
缺点是,您将不得不重新组装16位和32位值,如果有,在结构中找到,并在这样做时考虑到任何感兴趣的问题。如果您知道任何这样的值都是在16位或32位地址边界上找到的,您可以使用union‘short和long数组来完成这一任务,这可能是最好的,尽管有点不透明。
HTH
https://stackoverflow.com/questions/24791253
复制相似问题