6

我有这样的结构

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)
4

3 回答 3

8

不,这可能行不通,而且通常是一种糟糕而破碎的方式。

您必须使用特定于编译器的扩展来确保结构成员之间没有不可见的填充,这样才能工作。例如,使用 gcc,您可以使用__attribute__()语法来执行此操作。

因此,它不是一个可移植的想法。

最好明确一点,并解压缩每个字段。这也使您有机会在网络协议中具有明确定义的字节序,这通常是互操作性的好主意。

于 2013-04-15T14:05:26.800 回答
5

不,这通常不是有效的代码。您应该先制作结构,然后将内容复制到其中:

packet p;

memcpy(&p.seqnum, buf + 0, 4);

memcpy(&p.type[0], buf + 4, 1);

memcpy(&p.time1, buf + 5, 4);

等等。

您必须非常小心地获得正确的类型大小和字节序。

于 2013-04-15T14:06:28.030 回答
2

首先,您无法提前知道编译器将在结构中的何处插入填充字节以进行性能优化(缓存行对齐、整数对齐等),因为这取决于平台。当然,除非您正在考虑仅在您的平台上构建应用程序。

无论如何,在您的情况下,您似乎是从某个地方(网络?)获取数据,并且很可能数据已被压缩(字段之间没有填充字节)。

如果您真的想将数组类型转换为结构指针,您仍然可以告诉编译器删除它可能添加的填充字节。请注意,这取决于您使用的编译器,而不是标准的 C 实现。使用 gcc,您可以在结构定义的末尾添加以下语句:

struct my_struct {
    int blah;
    /* Blah ... */
} __attribute__((packed));

请注意,它会影响成员访问、复制等的性能......

除非你有很好的理由这样做,否则永远不要使用这个__attribute__((packed))东西!

另一个更可取的解决方案是自己进行解析。您只需分配一个适当的结构并通过从缓冲区中寻找好的信息来填充其字段。一系列memcpy指令可能会在这里解决问题(请参阅Kerrek的回答)

于 2013-04-15T14:08:44.897 回答