0

我有这个结构代表一个通用消息

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);`
4

2 回答 2

0

specific_msg_t与某些架构上的对齐要求可能不同generic_msg_t,该代码可能导致崩溃 - 编译器没有特殊要求将 generic_msg_t 对象对齐到适合访问双精度的边界上。

确切地知道您遇到了什么错误会有所帮助。

于 2013-06-17T15:50:02.823 回答
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”类型的消息。使用成员“选择器”来决定您收到的特定类型的消息,然后使用适当的特定类型来读取不同的数据成员。如果特定类型之间的大小差异很大,那么这是一个坏主意,但是如果您不受带宽的限制,那么它至少是可读的并且不容易出错。

于 2013-06-17T15:41:43.333 回答