1

嗨,我有以下联合,它是更大结构的一部分,我想在这个联合中存储一个 uint64_t(64 位大小)数据。但是我想通过访问 id_data 字段来存储它,因为其他字段不足以容纳完整的 uint64_t。但我不知道如何将我的 uint64_t 数据分配到这个 id_data 字段中。

我知道如何从这个字段中读取 uint64_t 数据。但不知如何为它赋值。

任何帮助将不胜感激。

谢谢。

union {
    struct id_ts {          /* ICMP Timestamp */
        uint32_t otime; /* Originate */
        uint32_t rtime; /* Receive */
        uint32_t ttime; /* Transmit */
    } id_ts;
    struct id_ip  {
        struct xyz_abc idi_ip;
        /* options and then 64 bits of data */
    } id_ip;
    struct ra_addr id_radv;
    uint32_t id_mask;
    char    id_data[1];
} icmp_nnn;
4

6 回答 6

1

你可以使用memcpy

uint64_t val;
memcpy((void*)&icmp_nnn.id_data[0], (void*)&val, sizeof(val));

您并没有真正将其分配给id_data成员。刚刚memcpy进入联合使用的内存空间。 id_data[0]对应于.union

于 2010-07-09T00:28:56.887 回答
0

呃……为什么不直接让一个 uint64_t 成为你可以分配到的工会的成员呢?

如所写,您不能将其写入 id_data 字段,因为该字段只有一个字节长。使用比这更多的空间(我相信)是实现定义的。

也就是说,您对联合所做的几乎任何事情都是无论如何定义的实现,因此,如果您想要讨厌的讨厌的严重疯狂的平台依赖方式来做到这一点,您可以使用位移来获得所需的效果。请注意,您可能需要更改

size_t idx = 0;
uint64_t myData = /* ... */;
union icmp_nnn structure;
for (; idx < 8; ++idx)
{
    // For big endian machines
    structure.id_data[idx] = (myData >> 8*idx) & 0xFF;
    // For little endian machines
    structure.id_data[7-idx] = (myData >> 8*idx) & 0xFF;
}

比利3

于 2010-07-09T00:25:33.727 回答
0

如果你不能改变union声明,memcpy应该仍然让你为所欲为。

于 2010-07-09T00:28:55.967 回答
0

有没有理由不能声明工会的 uInt64_t 成员?

你说你知道如何从 id_data 字段中读取 uint64_t 数据?你是怎么做到的?get应该和set没有太大区别吧?

于 2010-07-09T00:31:38.037 回答
0

从字段中读取:

uint64_t ui = *(uint64_t*)icmp_nnn.id_data;

写信到外地;

*(uint64_t*)icmp_nnn.id_data = 12345;

但实际上,如果它是您自己的代码(即不是库),您应该只向联合中添加一个 uint64_t 成员。

于 2010-07-09T00:36:13.357 回答
0

您应该使用memcpy(),但实际上没有理由将该id_data字段用作目标 - 只需使用整个联合本身,这更清楚地表达了您的意图。

uint64_t src;
memcpy(&icmp_nnn, &src, sizeof src);
于 2010-07-09T01:41:54.287 回答