以那种方式进行转换不起作用。
您可以执行“反序列化”操作。
尽管这可能比其他某些方法慢,但它允许您更好地控制协议(例如,结构成员顺序不必遵循协议)。而且,结构中可能会有填充,如果我们在结构的末尾添加(例如)
uint32_t test3;
,则会显示出来。
以下是代码:
#include <stdio.h>
#include <stdint.h>
typedef struct {
uint32_t test1;
uint16_t test2;
} Mst;
uint8_t myArray[6] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
uint32_t
get32(uint8_t **base)
{
uint8_t *ptr;
uint32_t val = 0;
ptr = *base;
for (int len = sizeof(uint32_t); len > 0; --len) {
val <<= 8;
val |= *ptr++;
}
*base = ptr;
return val;
}
uint16_t
get16(uint8_t **base)
{
uint8_t *ptr;
uint16_t val = 0;
ptr = *base;
for (int len = sizeof(uint16_t); len > 0; --len) {
val <<= 8;
val |= *ptr++;
}
*base = ptr;
return val;
}
int
main(void)
{
Mst myS;
uint8_t *arr = myArray;
myS.test1 = get32(&arr);
myS.test2 = get16(&arr);
printf("test1=%8.8X test2=%4.4X\n",myS.test1,myS.test2);
return 0;
}
更新:
是的,这样做可以,但我希望尽可能少地使用处理器。这是手动将字节放入正确顺序的方式。同时,过程Mst * struct_p = (Mst*)myArray
是安全的,因为在定义struct
时我使用了__attribute__((packed))
,只是忘记写了这个。
我打算提到/建议使用packed
作为可能性。
在任何情况下,您都可以使用[在GNU下]:byteswap.h
来获取bswap_*
。端点交换非常常见,因此这些[高度]针对给定架构进行了优化。它们甚至可以调用编译器内部函数(例如__builtin_bswap32
),这些函数利用架构具有的任何特殊指令(例如x86
具有bswap
指令,而arm
具有rev16
)。
因此,您可以执行以下操作[即用bswap_*
替换for
循环](例如):
#include <stdio.h>
#include <stdint.h>
#include <byteswap.h>
typedef struct {
uint32_t test1;
uint16_t test2;
uint32_t test3;
} __attribute__((__packed__)) Mst;
uint8_t myArray[] = {
0x01, 0x02, 0x03, 0x04,
0x05, 0x06,
0x07, 0x08, 0x09, 0x0A
};
void
getall(Mst *myS)
{
myS->test1 = bswap_32(myS->test1);
myS->test2 = bswap_16(myS->test2);
myS->test3 = bswap_32(myS->test3);
}
int
main(void)
{
Mst *myS = (Mst *) myArray;
getall(myS);
printf("test1=%8.8X test2=%4.4X test3=%8.8X\n",
myS->test1,myS->test2,myS->test3);
return 0;
}