我正在尝试与如下结构的C事件API进行交互:
struct EventA {
int type;
int data1;
int data2;
};
struct EventB {
int type;
int data1;
};
union Event {
int type;
EventA eventA;
EventB eventB;
};
//grabs the next event from the queue.
void pollEvent(Event *event);
在C API中,type
字段用于确定发生了什么类型的事件。这本质上是一个标记的联合,或Rust中的枚举。我知道Rust允许您使用#[repr(type)]
选择枚举的基础标签,但是我相信Rust不能保证该标签是枚举的第一个字段。 (还是它总是最后一个字段?)这在将API转换为Rust时有点麻烦,因为我需要某种类型的中间人结构来进行轮询,然后匹配其类型,将其转换为枚举,然后用户将与枚举。
如果我知道标记是枚举的第一个字段,则知道枚举和联合具有相同的内存表示形式,我可以将其作为指针传递。
我想做什么:
use::std::os::raw::c_int;
#[repr(C)]
#[derive(Copy, Clone)]
pub struct EventA {
pub data1: c_int,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct EventB {
pub data1: c_int,
pub data2: c_int,
}
#[repr(i32)] //I'm assuming c_int is 32 bit.
#[derive(Copy, Clone)]
pub enum Event {
// <---- Put the tag is here, followed the union memory,
A(EventA),
B(EventB),
}
extern {
pub fn pollEvents(*mut Event);
}
pub fn poll_events(*mut Event) {
unsafe {
pollEvents(*mut Event);
}
}
答案 0 :(得分:0)
有一个RFC可以保证在基本上允许您想要的枚举的枚举上使用#[repr(C, Int)]
时的布局。请注意,与往常一样,Rust只能做出最好的猜测,您应该在编译时为内存布局添加测试。