结构成员对齐 – 使用16位和32位编译器的不同sizeof
发布时间:2020-12-16 10:14:48 所属栏目:百科 来源:网络整理
导读:我有一个结构用于构建控制板的消息我需要保持C167 16位Keil编译器和32位Tricore gcc编译器之间的软件兼容性. typedef struct{ unsigned char new_weld_status[2]; UINT32 new_weld_count; UINT16 new_weld_fail_count;} NEW_PULSE_DATA; 数组new_weld_status
我有一个结构用于构建控制板的消息我需要保持C167 16位Keil编译器和32位Tricore
gcc编译器之间的软件兼容性.
typedef struct { unsigned char new_weld_status[2]; UINT32 new_weld_count; UINT16 new_weld_fail_count; } NEW_PULSE_DATA; 数组new_weld_status [2]在16位编译器上占用2个字节,在32位编译器上占用4个字节.我正在考虑用gcc编译时用union替换所有new_weld_status [2].但是有一个我可以用于gcc的开关,使chars适合/对齐2个字节? 谢谢 解决方法
请注意,您的结构布局会在32位系统上产生问题.许多(大多数)32位CPU架构需要对32位字进行4字节对齐,因此new_weld_count需要“填充”以提供适当的内存对齐.
typedef struct { unsigned char new_weld_status[2]; //a //char padding_1[2]; //hidden padding UINT32 new_weld_count; //a UINT16 new_weld_fail_count; //a } NEW_PULSE_DATA; 以下对结构的重新定义完全避免了这个问题. typedef struct { UINT32 new_weld_count; //a UINT16 new_weld_fail_count; //a unsigned char new_weld_status[2]; //a } NEW_PULSE_DATA; NEW_PULSE_DATA ex_PULSE_DATA; 然而,上述方法通常不是通过网络/通过消息传输来传输结构(ured)数据的方法.一种更常见且更好的方法是使用序列化/反序列化层(也称为编组)将结构放置在“线上”格式中.您当前的方法是将内存存储和寻址与通信格式混为一谈. //you need to decide on the size of wire format data,//Both ends of the protocol must agree on these sizes,#define new_weld_count_SZ sizeof(ex_PULSE_DATA.new_weld_count) #define new_weld_fail_count_SZ sizeof(ex_PULSE_DATA.new_weld_fail_count) #define new_weld_status_SZ sizeof(ex_PULSE_DATA.new_weld_status) //Then you define a network/message format typedef struct { byte new_weld_count[new_weld_count_SZ]; byte new_weld_fail_count[new_weld_count_SZ]; byte new_weld_status[new_weld_count_SZ]; } MESSAGE_FORMAT_PULSE_DATA; 然后你将实现序列化&反序列化功能在传输的两端.下面的例子很简单,但传达了你需要的要点. byte* PULSE_DATA_serialize( MESSAGE_FORMAT_PULSE_DATA* msg,NEW_PULSE_DATA* data ) { memcpy(&(msg->new_weld_count),data->new_weld_count,new_weld_count_SZ); memcpy(&(msg->new_weld_fail_count),data->new_weld_fail_count,new_weld_fail_count_SZ); memcpy(&(msg->new_weld_status),data->new_weld_status,new_weld_status_SZ); return msg; } NEW_PULSE_DATA* PULSE_DATA_deserialize( NEW_PULSE_DATA* data,MESSAGE_FORMAT_PULSE_DATA* msg ) { memcpy(data->new_weld_count,&(msg->new_weld_count),new_weld_count_SZ); memcpy(data->new_weld_fail_count,&(msg->new_weld_fail_count),new_weld_fail_count_SZ); memcpy(data->new_weld_status,&(msg->new_weld_status),new_weld_status_SZ); return msg; } 请注意,我省略了必须的网络字节顺序转换,因为我假设您已经解决了两个cpu域之间的字节顺序问题.如果你没有考虑字节顺序(big-endian和little-endian),那么你也需要解决这个问题. 发送邮件时,发件人执行以下操作, //you need this declared & assigned somewhere NEW_PULSE_DATA data; //You need space for your message MESSAGE_FORMAT_PULSE_DATA msg; result = send(PULSE_DATA_deserialize( &data,&msg )); 收到邮件时,收件人会执行以下操作, //recipient needs this declared somewhere NEW_PULSE_DATA data; //Need buffer to store received data MESSAGE_FORMAT_PULSE_DATA msg; result = receive(&msg,sizeof(msg)); //appropriate receipt checking here... PULSE_DATA_deserialize( &data,&msg ); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |