C 如何将结构重铸为u32?

C 如何将结构重铸为u32?,c,C,在我调用的API中,它有一个“ExtendedMode”字段,允许我传递特定于用户的扩展: 750 struct my_struct { 751 __u32 field1; 752 __u32 field2; 753 __u32 field3; 754 __u32 extendedmode; /* user extension */ 755 __u3

在我调用的API中,它有一个“ExtendedMode”字段,允许我传递特定于用户的扩展:

  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;
}
那么,如何将我的_ext(大小为u32)置于我的_结构的extendedmode


谢谢。

为什么不将
memcpy
值放入
extendedmode
插槽

my_struct my = ...;
my_ext ext = ...;
memcpy(&my.extendedmode, &ext, sizeof(ext));
或创建一个联盟:

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;
我认为@pat是正确的,但它只能在big-endian处理器中使用

对于小型endian处理器,union可以这样编写:

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

您还可以为
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;
}
\u32包(结构我的扩展){
返回(ext.ext1 24)&0xFF;
ext.ext2=(ext_val>>16)和0xFF;
ext.ext3=ext_val&0xFFFF;
返回ext;
}

用户将如何使用
扩展模式
?为什么字段的顺序很重要?只有当你打算在一台大端机上写一个值,然后在一台小端机上读它(反之亦然),它才会起作用。只要你在同一台机器上读写,顺序就不重要了。我在Intel PC上测试过,我确信字段的顺序确实重要。例如,我的ext的地址是0x2EFD20,这意味着ext1(值:0x01)在0x2EFD20中,ext2(值:0x02)在0x2EFD21中,ex3(值:0x0304)在0x2EFD22中,然后我通过ext.value获得0x03040201。如果结构的地址在大端中反转(当my_ext的地址为0x2EFD20时,ext1将在0x2EFD23中,ext2将在0x2EFD22中,ex3将在0x2EFD20中),字段的顺序无关紧要。我没有大端计算机,因此无法进行测试。字段的相对地址将是相同的,无论是否为端。在您的示例中,ext3将位于最低地址,ext1将位于最高地址。唯一的区别是,当访问多字节字段时,大端计算机机器将把最高有效位放在最低地址,一个小的端位机器将把最低有效位放在最低地址。32位压缩结果将显示不同,但这没关系,因为它总是由编译器一致地构造和解构。不需要改变字段的顺序,并且仍然不会使32位的值看起来相同,因为16位子字段中的单个字节仍然会显示为反向。这基本上就是
联合
所做的,但是有更多的语法。如果您确实关心字段是如何打包的,这肯定是一种方法(例如,因为你打算将它们以数据包的形式传输到另一台机器上),但如果你并不在意,为什么不让编译器为你挑选一个包装呢?@pat同意。我只是想提供另一个选择。
__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;
}