我有这样的结构
struct packet
{
int seqnum;
char type[1];
float time1;
float pri;
float time2;
unsigned char data[512];
}
我正在接收数据包
char buf[529];
我想把seqnum,数据全部分开。下面的类型转换工作..它给我的垃圾值。
struct packet *pkt;
pkt=(struct packet *)buf;
printf(" %d",pkt->seqnum)
答案 0 :(得分:8)
不,这可能不起作用,并且通常是一种糟糕而破碎的方式。
您必须使用特定于编译器的扩展来确保结构成员之间没有不可见的填充,以实现类似的功能。例如,使用gcc,您可以使用__attribute__()
语法执行此操作。
因此,这不是一个便携式的想法。
要明确它,并打开每个字段,这要好得多。这也使您有机会在网络协议中定义明确的 endianness ,这通常是互操作性的好主意。
答案 1 :(得分:5)
不,这通常不是有效的代码。您应首先制作结构,然后将内容存储到其中:
packet p;
memcpy(&p.seqnum, buf + 0, 4);
memcpy(&p.type[0], buf + 4, 1);
memcpy(&p.time1, buf + 5, 4);
等等。
您必须非常小心地确定类型大小和字节顺序。
答案 2 :(得分:2)
首先,您无法事先知道编译器将在结构中插入填充字节以进行性能优化(缓存行对齐,整数对齐等),因为这与平台有关。当然,除非您考虑仅在您的平台上构建应用程序。
无论如何,在您的情况下,您似乎从某个地方(网络?)获取数据,并且很可能数据已被压缩(字段之间没有填充字节)。
如果您确实想将数组强制转换为结构指针,您仍然可以告诉编译器删除它可能添加的填充字节。请注意,这取决于您使用的编译器,而不是标准C实现。使用gcc,您可以在结构定义的末尾添加此语句:
struct my_struct {
int blah;
/* Blah ... */
} __attribute__((packed));
请注意,它会影响成员访问,复制等的性能......
除非你有充分的理由这样做,否则不要使用__attribute__((packed))
的东西!
另一个更可取的解决方案是自行解析。您只需通过从缓冲区中查找好的信息来分配适当的结构并填充其字段。一系列memcpy
指令可能会在这里发挥作用(参见Kerrek的回答)