6个版本 (重大更新)

0.18.0 2023年6月2日
0.17.0 2023年2月1日
0.3.0 2019年8月15日
0.2.0 2019年6月7日
0.1.0 2019年4月9日

#38FFI

Download history 6518/week @ 2024-04-21 5370/week @ 2024-04-28 5153/week @ 2024-05-05 6363/week @ 2024-05-12 6734/week @ 2024-05-19 6588/week @ 2024-05-26 7921/week @ 2024-06-02 6855/week @ 2024-06-09 7395/week @ 2024-06-16 8644/week @ 2024-06-23 8104/week @ 2024-06-30 9410/week @ 2024-07-07 10374/week @ 2024-07-14 10777/week @ 2024-07-21 10068/week @ 2024-07-28 9874/week @ 2024-08-04

41,899 每月下载量
用于 52 个crate(13个直接使用)

BSD-3-Clause

28KB
618

C2Rust-Bitfields Crate

此crate用于在c2rust翻译中生成包含位域的struct。它有三个主要目标

  • 与等效C位域struct的字节兼容性
  • 能够引用/指向非位域字段
  • 提供读取和写入位域的方法

我们目前提供一个自定义 derive,BitfieldStruct,以及一个相关字段属性 bitfield。相关字段属性 padding 可用作无操作的标记,供自动化工具使用。

要求

  • Rust 1.30+
  • Rust Stable,Beta或Nightly
  • 小端架构

示例

假设您想编写一个非常紧凑的日期struct,它只占用三个字节。在C中,这看起来像这样

struct date {
    unsigned char day: 5;
    unsigned char month: 4;
    unsigned short year: 15;
} __attribute__((packed));

Clang很有帮助地提供了这些信息

*** Dumping AST Record Layout
         0 | struct date
     0:0-4 |   unsigned char day
     0:5-8 |   unsigned char month
    1:1-15 |   unsigned short year
           | [sizeof=3, align=1]

这足以构建我们的rust struct

#[repr(C, align(1))]
#[derive(BitfieldStruct)]
struct Date {
    #[bitfield(name = "day", ty = "libc::c_uchar", bits = "0..=4")]
    #[bitfield(name = "month", ty = "libc::c_uchar", bits = "5..=8")]
    #[bitfield(name = "year", ty = "libc::c_ushort", bits = "9..=23")]
    day_month_year: [u8; 3]
}

fn main() {
    let mut date = Date {
        day_month_year: [0; 3]
    };

    date.set_day(18);
    date.set_month(7);
    date.set_year(2000);

    assert_eq!(date.day(), 18);
    assert_eq!(date.month(), 7);
    assert_eq!(date.year(), 2000);
}

此外,还考虑了C位域的溢出和有符号整数的规则。

当提供 no_std 功能标志时,此crate可以生成与 no_std 兼容的代码。

测试

由于Rust不支持为测试单独创建一个 build.rs 文件,您必须手动编译C测试代码并将其链接进来。

$ clang tests/bitfields.c -c -fPIC -o tests/bitfields.o
$ ar -rc tests/libtest.a tests/bitfields.o
$ RUSTFLAGS="-L `pwd`/tests" cargo test

致谢

这个crate受到了rust-bitfieldpacked_structbindgen crate的启发。

依赖项

~1.5MB
~35K SLoC