Is there any way to do this with a cast?
Yes it is possible, with the following assumptions:
You need to take care of the struct alignment (compiler specific):
#pragma pack(push, 1) ... #pragma pack(pop)
,
__attribute__((packed))
, etc.
You need to take care of the endianess between your architecture and the bytes in a buffer (make a conversion if needed)
What you can do is to use void* c
instead of uint8_t* c
in the struct and then cast void*
to a explicit pointer type.
Example 1:
#include <stdint.h>
#include <stdio.h>
#pragma pack(push, 1)
typedef struct {
uint8_t a;
uint16_t b;
void* c;
} req;
#pragma pack(pop)
void f(uint8_t* Buf)
{
req* r = (req*)Buf;
printf("a: %02x\n", r->a);
printf("b: %04x\n", r->b);
printf("c: %02x\n", ((uint8_t*)&r->c)[0]);
}
int main()
{
uint8_t buf[] = { 0x01, 0x02, 0x03, 0x04 };
f(buf);
return 0;
}
Output:
a: 01
b: 0302
c: 04
Example 2:
#include <stdint.h>
#include <stdio.h>
#pragma pack(push, 1)
typedef struct {
uint8_t a;
uint16_t b;
void* c;
} req;
typedef struct {
uint8_t cmd;
uint16_t value;
} SubPacket;
#pragma pack(pop)
void f(uint8_t* Buf)
{
req* r = (req*)Buf;
printf("a: %02x\n", r->a);
printf("b: %04x\n", r->b);
SubPacket* sub_packet = (SubPacket*)&r->c;
printf("cmd: %02x\n", sub_packet->cmd);
printf("value: %04x\n", sub_packet->value);
}
int main()
{
uint8_t buf[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
f(buf);
return 0;
}
Output:
a: 01
b: 0302
cmd: 04
value: 0605