diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index e070df8d90..81a21fea8e 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -19,4 +19,5 @@ - [Preventing the Derivation of `Copy` and `Clone`](./nocopy.md) - [Generating Bindings to C++](./cpp.md) - [Using Unions](./using-unions.md) +- [Using Bitfields](./using-bitfields.md) - [FAQ](./faq.md) diff --git a/book/src/using-bitfields.md b/book/src/using-bitfields.md new file mode 100644 index 0000000000..c6d2c7e80e --- /dev/null +++ b/book/src/using-bitfields.md @@ -0,0 +1,89 @@ +# Using the Bitfield Types Generated by Bindgen + +## Bitfield Strategy Overview + +As Rust does not support bitfields, Bindgen generates a struct for each with the following characteristics +* Immutable getter functions for each bitfield named `````` +* Setter functions for each contiguous block of bitfields named ```set_``` +* Far each contiguous block of bitfields, Bindgen emits an opaque physical field that contains one or more logical bitfields +* A static constructor ```new_bitfield_{1, 2, ...}``` with a parameter for each bitfield contained within the opaque physical field. + +## Bitfield examples + +For this discussion, we will use the following C type definitions and functions. +```c +typedef struct { + unsigned int a: 1; + unsigned int b: 1; + unsigned int c: 2; + +} StructWithBitfields; + +// Create a default bitfield +StructWithBitfields create_bitfield(); + +// Print a bitfield +void print_bitfield(StructWithBitfields bfield); +``` + +Bindgen creates a set of field getters and setters for interacting with the bitset. For example, + +```rust,ignore + let mut bfield = unsafe { create_bitfield() }; + + bfield.set_a(1); + println!("a set to {}", bfield.a()); + bfield.set_b(1); + println!("b set to {}", bfield.b()); + bfield.set_c(3); + println!("c set to {}", bfield.c()); + + unsafe { print_bitfield(bfield) }; +``` + +will print out + +```text +a set to 1 +b set to 1 +c set to 3 +StructWithBitfields: a:1, b:1, c:3 +``` + +Overflowing a bitfield will result in the same behavior as in C/C++: the bitfield will be set to 0. + +```rust,ignore + let mut bfield = unsafe { create_bitfield() }; + bfield.set_a(1); + bfield.set_b(1); + bfield.set_c(12); + println!("c set to {} due to overflow", bfield.c()); + + unsafe { print_bitfield(bfield) }; +``` + +will print out + +```text +c set to 0 due to overflow +StructWithBitfields: a:1, b:1, c:0 +``` + +To create a new bitfield in Rust, use the bitfield allocation unit constructor. + +Note: This requires the Builder's derive_default to be set to true, otherwise the necessary Default functions won't be generated. + +```rust,ignore + let bfield = StructWithBitfields{ + _bitfield_1: StructWithBitfields::new_bitfield_1(0,0,0), + ..Default::default() + }; + + unsafe { print_bitfield(bfield) }; +``` + +This will print out + +```text +StructWithBitfields: a:1, b:0, c:2 +```