C++ 联合结构中的额外数据元素
我试图将一个相对复杂的消息编码到一个联合结构中,这样我就可以生成一个uint8_t数组,并将其输入到串行通信协议中 但是,当查看在我的union中填充数据时生成的数组时,在我的命令类型元素之后会出现一个额外的uint8\u t元素。请参见下面的工会结构:C++ 联合结构中的额外数据元素,c++,arrays,structure,unions,C++,Arrays,Structure,Unions,我试图将一个相对复杂的消息编码到一个联合结构中,这样我就可以生成一个uint8_t数组,并将其输入到串行通信协议中 但是,当查看在我的union中填充数据时生成的数组时,在我的命令类型元素之后会出现一个额外的uint8\u t元素。请参见下面的工会结构: union myint16_t{ uint16_t ui16; int16_t i16; uint8_t data[2]; }; union { struct {
union myint16_t{
uint16_t ui16;
int16_t i16;
uint8_t data[2];
};
union {
struct {
uint8_t commandtype;
myint16_t UpperLimits[4];
myint16_t LowerLimits[4];
myint16_t JointZeros[4];
int8_t JointPolarity[4];
myint16_t P[4];
myint16_t I[4];
myint16_t D[4];
};
uint8_t data[53];
};
如您所见,第二个匿名联合引用了联合myint16\t。
因此,如果我填充匿名联合的所有值,然后打印出基础数据[53]数组,那么我的第二个值(数据[1])是0,而不是上限[4]的第一个元素的一部分。请参阅代码,我在其中填充联合体,然后打印出元素
char q = 'c';
hmmv4_configmsg msg;
msg.commandtype =(uint8_t) q;
msg.UpperLimits[0].ui16 = 784;
msg.UpperLimits[1].ui16 = 784;
msg.UpperLimits[2].ui16 = 784;
msg.UpperLimits[3].ui16 = 784;
msg.LowerLimits[0].ui16 = 223;
msg.LowerLimits[1].ui16 = 223;
msg.LowerLimits[2].ui16 = 223;
msg.LowerLimits[3].ui16 = 223;
msg.JointZeros[0].ui16 = 512;
msg.JointZeros[1].ui16 = 512;
msg.JointZeros[2].ui16 = 512;
msg.JointZeros[3].ui16 = 512;
msg.JointPolarity[0] = -1;
msg.JointPolarity[1] =-1;
msg.JointPolarity[2] =-1;
msg.JointPolarity[3] =-1;
msg.P[0].i16=4000;
msg.P[1].i16=4000;
msg.P[2].i16=4000;
msg.P[3].i16=4000;
msg.I[0].i16=1;
msg.I[1].i16=1;
msg.I[2].i16=1;
msg.I[3].i16=1;
msg.D[0].i16=24;
msg.D[1].i16=24;
msg.D[2].i16=24;
msg.D[3].i16=24;
//msg.change_endian();
while(1)
{
for(int i =0; i<54; i++)
{
writebuf[i]=msg.data[i];
printf("D: %d, %d \n", i, msg.data[i]);
}
printf("L0: %d, %d, %d", msg.P[0].i16, msg.P[0].data[0], msg.P[0].data[1]);
int r =jointencoder.xfer1(writebuf, readbuf, 54);
}
我的问题是为什么D:1会出现?我对联合和结构的理解是,因为命令类型是uint8_t,所以它应该只占用一个数据空间,因此上限[0]应该从D:1开始,但似乎命令类型充当uint16_t并发布另一位。为什么会这样
注意:您可能会看到索引上升到计数数据[53],这应该是超出范围的,但我需要读取并发送它,以便能够解构另一端的数据。几乎可以肯定,在
commandtype
和上限之间有一个填充字节;2字节myint16\t
数据类型在偶数字节边界上对齐
struct {
uint8_t commandtype;
myint16_t UpperLimits[4];
...
如果您可以打印匿名结构和联合的大小,您可能会发现它至少是54字节(您认为应该是53字节)。作为联合的匿名成员嵌入的未标记结构类型的缺点之一是,无法轻松打印结构的大小。为结构指定一个标记(struct tag{uint8\u t commandtype;…
),以便打印出其大小
使用当前框架无法轻松解决此问题。您需要告诉编译器如何对齐并集或结构中的元素。只需在定义之前添加#pragma pack(push,1),指示编译器对齐单字节边界上的相邻元素,然后使用#pragma pack(pop)还原为编译器的默认对齐方式。出于性能原因,您不希望对所有结构/联合/类使用单字节对齐方式,因此最好将联合定义封装在pragma对中
例如:
#pragma pack(push,1)
union
{
uint_8 first;
uint_8 second;
} two_bytes;
#pragma pack(pop)
assert(sizeof two_bytes == 2);
#pragma pack(push,1)
union
{
uint_8 first;
uint_8 second;
} two_bytes;
#pragma pack(pop)
assert(sizeof two_bytes == 2);