如何将结构重铸为u32?

时间:2014-03-21 05:08:25

标签: c

在我调用的API中,它有一个&扩展模式'允许我通过用户特定扩展名的字段:

  750 struct my_struct {
  751     __u32          field1;   
  752     __u32          field2;   
  753     __u32          field3;
  754     __u32          extendedmode; /* user extension */
  755     __u32              field4; 
  756     __u32          reserved[4];
  757 };

所以我想用那个字段把我的结构放在那里。

struct my_ext {
   _8  ext1;
   _8  ext2;
   _16 ext3;
}

那么如何将my_ext(大小为u32)放在my_struct的扩展模式下呢?

谢谢。

4 个答案:

答案 0 :(得分:2)

In the case of the following order of the fields:
  extendedmode     bit31-bit16  bit15-bit8 bit7-bit0
                   |            |          |
  my_ext           _16 ext3     _8 ext2    _8 ext1

我认为@pat是正确的,但它只能在大端处理器中使用。

对于一个小端处理器,联合可能是这样写的:

union my_ext {
    _32 value;
    struct my_ext {
       _16 ext3;
       _8  ext2;
       _8  ext1;
    };
}

答案 1 :(得分:1)

为什么不将memcpy值放入extendedmode广告位?

my_struct my = ...;
my_ext ext = ...;
memcpy(&my.extendedmode, &ext, sizeof(ext));

答案 2 :(得分:1)

或者创建一个联盟:

union my_ext {
    _32 value;
    struct my_ext {
       _8  ext1;
       _8  ext2;
       _16 ext3;
    };
}

my_struct my = ...;
my_ext ext = ...;
ext.ext1 = ...;
ext.ext2 = ...;
ext.ext3 = ...;
my.extendedmode = ext.value;

答案 3 :(得分:0)

您还可以为struct my_ext实现自己的打包和解压缩功能。例如,

__u32 pack(struct my_ext ext) {
    return (ext.ext1 << 24) | (ext.ext2 << 16) | ext.ext3;
}

struct my_ext unpack(__u32 ext_val) {
    struct my_ext ext;
    ext.ext1 = (ext_val >> 24) & 0xFF;
    ext.ext2 = (ext_val >> 16) & 0xFF;
    ext.ext3 = ext_val & 0xFFFF;
    return ext;
}