如何将混合类型联合数组转换为uint8_t数组并还原?
嘿,我完全懂你遇到的问题——直接用指针赋值或者整体赋值肯定行不通,C语言不允许不同类型的数组/联合体直接这么操作。咱们直接来解决这个问题:
核心问题分析
你写的*spi_arr=*inst1本质是把整个联合体数组的首元素赋值给单个uint8_t变量,类型完全不匹配,编译器当然会报错。正确的思路是原样拷贝内存字节,因为你的联合体和uint8_t数组在内存中都是连续的字节块,用memcpy就能完美实现双向转换。
修改后的完整代码
#include <stdio.h> #include <string.h> // 必须包含这个头文件才能用memcpy #include <stdint.h> int main() { int len = 4; union dummy { float f32; uint32_t u32; uint8_t u8[4]; }; union dummy inst1[len]; // 源单片机实例 union dummy inst2[len]; // 目标单片机实例 uint8_t spi_arr[4 * len]; // 初始化源端测试数据 inst1[0].u8[0] = 73; inst1[1].f32 = 17.5; inst1[2].u32 = 0x12345678; inst1[3].f32 = -42.0; printf("Source Data:\n"); printf("inst1[0].u8[0] = %d\n", inst1[0].u8[0]); printf("inst1[1].f32 = %.2f\n", inst1[1].f32); printf("inst1[2].u32 = 0x%X\n", inst1[2].u32); printf("inst1[3].f32 = %.2f\n", inst1[3].f32); // 源端:把联合体数组的内存原样拷贝到SPI字节数组 memcpy(spi_arr, inst1, sizeof(spi_arr)); // -------------------------- // 这里省略实际SPI发送/接收代码 // -------------------------- // 目标端:把SPI字节数组的内存原样拷贝回联合体数组 memcpy(inst2, spi_arr, sizeof(inst2)); printf("\nTarget Data:\n"); printf("inst2[0].u8[0] = %d\n", inst2[0].u8[0]); printf("inst2[1].f32 = %.2f\n", inst2[1].f32); printf("inst2[2].u32 = 0x%X\n", inst2[2].u32); printf("inst2[3].f32 = %.2f\n", inst2[3].f32); return 0; }
关键注意事项
- 必须包含
<string.h>:memcpy函数定义在这个头文件里,漏掉会导致编译错误。 - 用
sizeof自动计算拷贝长度:避免手动计算字节数出错,sizeof(spi_arr)和sizeof(inst2)会自动返回正确的总字节数。 - 字节序(Endianness)坑:如果源和目标单片机的架构不同(比如一个是大端,一个是小端),多字节类型(
float、uint32_t)还原后会出现错误。这时候需要统一字节序:- 源端:把多字节类型转换成网络字节序(大端),比如:
// 处理uint32_t uint32_t big_endian_u32 = htonl(inst1[2].u32); memcpy(inst1[2].u8, &big_endian_u32, 4); // 处理float:先转成uint32_t再转字节序 uint32_t float_as_u32 = *(uint32_t*)&inst1[1].f32; float_as_u32 = htonl(float_as_u32); memcpy(inst1[1].u8, &float_as_u32, 4); - 目标端:把接收到的字节转回到本地字节序:
uint32_t big_endian_u32; memcpy(&big_endian_u32, inst2[2].u8, 4); inst2[2].u32 = ntohl(big_endian_u32);
- 源端:把多字节类型转换成网络字节序(大端),比如:
内容的提问来源于stack exchange,提问作者Caniko
相关产品推荐
相关产品推荐

