Struct 具有混合bitflag和普通成员的结构

Struct 具有混合bitflag和普通成员的结构,struct,rust,ffi,bit-fields,bitflags,Struct,Rust,Ffi,Bit Fields,Bitflags,我正在尝试为FFI重新创建一个包含混合位字段成员和Rust中“普通”成员的C结构 我已经读到,将是一个去,不幸的是,我发现文件缺乏关于如何实际工作的语法 bitflags板条箱使使用枚举以类似于C中的样式创建位掩码变得更容易。声明创建可以访问的位字段,但是我不知道它是如何工作的 我有这样一个C结构: struct混合{ 无符号整数标志_1_1:1; 无符号整数标志_2_7:7; 无符号整数标志_3_8:8; 无符号整数; 无符号int-some_-val2; 无符号整数标志_4_16:16; }

我正在尝试为FFI重新创建一个包含混合位字段成员和Rust中“普通”成员的C结构

我已经读到,将是一个去,不幸的是,我发现文件缺乏关于如何实际工作的语法

bitflags板条箱使使用枚举以类似于C中的样式创建位掩码变得更容易。声明创建可以访问的位字段,但是我不知道它是如何工作的

我有这样一个C结构:

struct混合{
无符号整数标志_1_1:1;
无符号整数标志_2_7:7;
无符号整数标志_3_8:8;
无符号整数;
无符号int-some_-val2;
无符号整数标志_4_16:16;
};
我不知道如何在Rust中表示它,我会使用板条箱来访问
c_uint
,但除此之外,我目前几乎没有想法,找到其他这样做的代码也没有被证明是成功的:

#[repr(transparent)]//我也需要repr(C)吗?
结构混合{
标志(1)3:混合标志(1)3 ;;
一些价值1:成本;
一些价值2:成本;
标志4:混合标志4;
}
比特菲尔德!(
#[repr(transparent)]//我这里也需要repr(C)吗?
结构混合\u标志\u 1\u 3(u16/*此参数如何?*/){
u8;//这是什么意思?
/*获取/字段,设置:第一位,最后一位*/
标志_1_1,_:0,0;
标志2,7,7,1;
旗帜3,8,15,8,;
}
)
比特菲尔德!(
#[报告(透明)]
结构混合_标志_4(u8){
u8;
标志4,16,15,0;
}
)

这些只是猜测,如何创建正确的表示?

在这种情况下,您可以通过以下方式查看genearted代码:

$bindgen test.h
#[报告员(C)]
#[派生(复制、克隆、调试、默认、Eq、哈希、Ord、PartialEq、PartialOrd)]
发布结构\uuuu BindgenBitfieldUnit
哪里
存储:AsRef+AsMut,
{
存储:存储,
align:[align;0],
}
//使用位字段的访问方法跳过代码
#[报告员(C)]
#[派生(调试、复制、克隆)]
pub结构混合{
pub_bitfield_1:uu BindgenBitfieldUnit,
pub some_val1:::std::os::raw::c_uint,
pub some_val2:::std::os::raw::c_uint,
pub_bitfield_2:uu BindgenBitfieldUnit,
pub_uubindgen_padding_0:u16,
}
使用
rustc--Z不稳定选项--pretty=expanded
我想我可以看出宏是这样做的,这似乎产生了一些可能是正确的,但是这可能只有在编译器不尝试填充或重新排序结构中的位字段时才兼容

#[repr(transparent)]//我也需要repr(C)吗?
结构混合{
标志(1)3:混合标志(1)3 ;;
一些价值1:成本;
一些价值2:成本;
标志4:混合标志4;
}
比特菲尔德!(
#[repr(transparent)]//我这里也需要repr(C)吗?
//结果是“元组结构”,即u16=位字段的总大小
结构混合_标志_1_3(u16){
//以下所有字段的值都应视为
//访问时不带符号的int
c_uint;
/*获取/字段,设置:第一位,最后一位*/
标志_1_1,_:0,0;
标志2,7,7,1;
//如果愿意,可以在此处再次更改类型:
//u16
旗帜3,8,15,8,;
}
)
比特菲尔德!(
#[报告(透明)]
结构混合_标志_4(u16){
c_uint;
标志4,16,15,0;
}
)

但至少现在,我认为我将只使用libclang和bindgen作为依赖项,并自动生成绑定,因为上面提到的平台兼容性问题。

您不需要位标志,而是需要位字段。它们不是一回事。重复的。哦,我被链接bitflags板条箱的答案弄糊涂了。现在这是有道理的。但是没有关于创建的位标志是否兼容的文档。这可能是不可能的,因为它是特定于编译器的,所以我不得不用C编写访问器函数。然而,C标准并没有向您承诺布局,所以bindgen创建的绑定只适用于您当前开发的平台。我想知道bitfield宏是否能处理这个问题,但我实际上根本无法理解它应该做什么,文档似乎有点缺乏。我刚刚在我的板条箱中使用了bingen,这是另一个附加的依赖项,但否则很难保持便携性。
$ bindgen test.h

#[repr(C)]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct __BindgenBitfieldUnit<Storage, Align>
where
    Storage: AsRef<[u8]> + AsMut<[u8]>,
{
    storage: Storage,
    align: [Align; 0],
}

//skipped code with access method for bit fields 

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct mixed {
    pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize], u8>,
    pub some_val1: ::std::os::raw::c_uint,
    pub some_val2: ::std::os::raw::c_uint,
    pub _bitfield_2: __BindgenBitfieldUnit<[u8; 2usize], u16>,
    pub __bindgen_padding_0: u16,
}