将uint64_t数据类型存储在C中的联合中存在的char类型字段中

时间:2010-07-09 00:22:38

标签: c struct unions

您好我有以下联合,它是更大的结构的一部分,我想在此联合中存储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;

6 个答案:

答案 0 :(得分:1)

您可以使用memcpy

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

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

答案 1 :(得分:0)

错误......为什么不只是创建一个你可以指定的联合的uint64_t成员?

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

也就是说,你使用union做的任何事情都是实现定义的,所以如果你想要讨厌令人讨厌的疯狂疯狂平台依赖的方式,你可以使用位移来获得所需的效果。请注意,您可能需要更改

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;
}

Billy3

答案 2 :(得分:0)

如果您无法更改union声明,memcpy仍然可以让您按照自己的意愿行事。

答案 3 :(得分:0)

你有没有理由不能宣布工会的uInt64_t成员?

您说您知道如何从id_data字段中读取uint64_t数据吗?你是怎么做到的? get应该与set没有太大的不同?

答案 4 :(得分:0)

从现场阅读:

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

写入字段;

*(uint64_t*)icmp_nnn.id_data = 12345;

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

答案 5 :(得分:0)

你应该使用memcpy(),但是没有理由使用id_data字段作为目的地 - 只需使用整个联盟本身,这可以更明确地表达你的意图。

uint64_t src;
memcpy(&icmp_nnn, &src, sizeof src);