Instantly share code, notes, and snippets.

@Gankro /_lib.rs
Last active Dec 16, 2018

Embed
What would you like to do?
cbindgen bridging Rust tagged unions into C++
// Rust Library
#[repr(u8)]
pub enum DisplayItem {
Fill(Rect, Color),
Image { id: u32, bounds: Rect },
ClearScreen,
}
#[repr(C)]
pub struct Rect { x: f32, y: f32, w: f32, h: f32 }
#[repr(C)]
pub struct Color { r: u8, g: u8, b: u8, a: u8 }
#[no_mangle]
pub extern "C" fn push_item(item: DisplayItem) -> bool {
::std::mem::drop(item);
true
}
// output of running cbindgen on the above crate
#include <cstdint>
#include <cstdlib>
struct Rect {
float x;
float y;
float w;
float h;
};
struct Color {
uint8_t r;
uint8_t g;
uint8_t b;
uint8_t a;
};
union DisplayItem {
enum class Tag : uint8_t {
Fill,
Image,
ClearScreen,
};
struct Fill_Body {
Tag tag;
Rect _0;
Color _1;
};
struct Image_Body {
Tag tag;
uint32_t id;
Rect bounds;
};
Tag tag;
Fill_Body fill;
Image_Body image;
};
extern "C" {
bool push_item(DisplayItem item);
} // extern "C"
@petertodd

This comment has been minimized.

Copy link

petertodd commented Dec 16, 2018

Note that this example is actually broken, with rustc -Z print-type-sizes showing:

print-type-size type: `DisplayItem`: 24 bytes, alignment: 4 bytes
print-type-size     discriminant: 1 bytes
print-type-size     variant `Fill`: 23 bytes
print-type-size         field `.1`: 4 bytes
print-type-size         padding: 3 bytes
print-type-size         field `.0`: 16 bytes, alignment: 4 bytes
print-type-size     variant `Image`: 23 bytes
print-type-size         padding: 3 bytes
print-type-size         field `.id`: 4 bytes, alignment: 4 bytes
print-type-size         field `.bounds`: 16 bytes
print-type-size     variant `ClearScreen`: 0 bytes

Note how the Fill variant's fields are in the wrong order.

See rust-lang/rust#56619 for more info.

@petertodd

This comment has been minimized.

Copy link

petertodd commented Dec 16, 2018

I'm curious: did you actually test this example? I'm not sure yet if this is a regression or an oversight.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment