我有这个结构代表一般信息
typedef struct {
uint16_t length;
uint8_t type1;
uint8_t type2;
uint8_t *data;
} generic_msg_t;
在读取type1和type 2之后,我可以知道它对应哪个特定的消息,例如:
typedef struct {
uint16_t length;
uint8_t type1;
uint8_t type2;
uint16_t a;
uint8_t b;
uint8_t c;
double d;
double e;
double f;
double g;
double h;
uint8_t i;
} specific_msg_t;
假设msg包含已验证的数据,我想了解为什么如果我这样做,我无法访问d,e,f,g,h数据(但是a,b,c)
specific_msg_t * specific_msg = (specific_msg_t *) msg;
uint16_t a = specific_msg->a; //OK
double d = specific_msg->d; //NOK`
我必须这样做:
unsigned char * buffer = (unsigned char *) msg;
double d = buffer[15] + (buffer[14] << 8) + (buffer[13] << 16) + (buffer[12] << 24) + (buffer[11] << 32) + (buffer[10] << 40) + (buffer[9] << 48) + (buffer[8] << 56);`
答案 0 :(得分:0)
只要发送方和接收方使用相同的标头(uint16_t对于它们两者都相同)并且它们都使用相同的体系结构(例如x86或其他),就不应该有太多问题。 我还会定义一个你需要的所有特定消息类型的联合,以避免那些讨厌的计算和大多数演员。 类似的东西:
typedef struct {
uint16_t length;
uint8_t type1;
uint8_t type2;
// whatever you need here...
double a;
float b;
// etc.
} specific_msg_t1;
typedef struct {
uint16_t length;
uint8_t type1;
uint8_t type2;
uint16_t a;
uint8_t b;
uint8_t c;
double d;
double e;
double f;
double g;
double h;
uint8_t i;
} specific_msg_t2;
typedef struct
{
uint16_t length;
uint8_t type1;
uint8_t type2;
} selector_msg_t;
typedef union
{
selector_msg_t selector;
specific_msg_t1 msgtype1;
specific_msg_t2 msgtype2;
} message_type_t;
使用此设置,您可以发送“message_type_t”类型的消息。使用成员“selector”决定您收到的特定类型的消息,然后使用适当的特定类型来读取不同的数据成员。 如果特定类型之间的大小差异相当大,那么这是一个坏主意,但如果您不受带宽的限制,那么它至少是可读的而不是容易出错的。
答案 1 :(得分:0)
specific_msg_t
可能具有与generic_msg_t
不同的对齐要求,因此在某些体系结构上,该代码可能会导致崩溃 - 编译器没有特别要求将generic_msg_t对象与适合访问的边界对齐双
确切地知道你会得到什么错误会有所帮助。