memcpy拷贝结构体时丢字节且字节序异常的问题求助
传感器数据提取的字节序与结构体解析问题
问题代码
主函数代码
void app_main(void) { esp_err_t err; uint8_t injected_input[]={0xCE,0x33,0xE1,0x00,0x11,0x22,0x33,0x44,0x55,0x66}; model_sensor_data_t stuff = {0}; model_sensor_data_t* sensor_buf = &stuff; if (extract_sensor_data_msgA(injected_input, sensor_buf) == -1) { ESP_LOGE(TAG, "Error in extract_sensor_data_msgA"); } ESP_LOGI(TAG, "extracted sensor data is 0x%12x", *sensor_buf); }
结构体与提取函数代码
typedef struct __attribute__((packed)) { uint8_t byte0; uint8_t byte1; uint8_t byte2; uint8_t byte3; uint8_t byte4; } model_sensor_data_t; int32_t extract_sensor_data_msgA(uint8_t *buf, model_sensor_data_t *sensor_buf) { if (buf == NULL || sensor_buf == NULL) { return -1; } //do other checks, blah blah memcpy(sensor_buf, buf + 5, sizeof(model_sensor_data_t)); //problem lies here return 0; }
问题现象
预期输出:CLIENT: extracted sensor data is 0x2233445566
实际输出:CLIENT: extracted sensor data is 0x 55443322
问题分析
- 填充问题不成立:结构体成员都是
uint8_t,连续单字节成员默认不会产生内存填充,__attribute__((packed))在这里无实际作用。 - 字节序与打印错误:
- ESP32是小端字节序架构,内存低地址存储数值的低位字节。
- 用
%x直接打印结构体属于未定义行为:%x要求整数类型参数,编译器会将结构体内存按整数解析,且%x默认处理32位整数,只会读取结构体前4个字节(0x22, 0x33, 0x44, 0x55),按小端顺序组合成0x55443322。
解决方法
方法1:按顺序打印结构体成员
直接逐个打印每个字节,保证输出顺序符合预期:
ESP_LOGI(TAG, "extracted sensor data is 0x%02x%02x%02x%02x%02x", sensor_buf->byte0, sensor_buf->byte1, sensor_buf->byte2, sensor_buf->byte3, sensor_buf->byte4);
此方式严格按byte0到byte4的顺序输出十六进制值,得到预期结果。
方法2:手动组合成大端序整数
若需将5个字节作为整体数值处理,手动按大端序组合为64位整数:
uint64_t combined_data = ((uint64_t)sensor_buf->byte0 << 32) | ((uint64_t)sensor_buf->byte1 << 24) | ((uint64_t)sensor_buf->byte2 << 16) | ((uint64_t)sensor_buf->byte3 << 8) | sensor_buf->byte4; ESP_LOGI(TAG, "extracted sensor data is 0x%010llx", combined_data);
使用uint64_t避免溢出,%010llx确保输出10位补零的十六进制数。
内容的提问来源于stack exchange,提问作者Iberico
相关产品推荐
相关产品推荐

