我试图从C库SDL_PollEvent
调用函数SDL2
。我知道已有包装,但我想创建自己的包装,只是为了学习。该函数需要一个指向此C联合的指针:
typedef union{
Uint8 type;
SDL_ActiveEvent active;
SDL_KeyboardEvent key;
SDL_MouseMotionEvent motion;
SDL_MouseButtonEvent button;
SDL_JoyAxisEvent jaxis;
SDL_JoyBallEvent jball;
SDL_JoyHatEvent jhat;
SDL_JoyButtonEvent jbutton;
SDL_ResizeEvent resize;
SDL_ExposeEvent expose;
SDL_QuitEvent quit;
SDL_UserEvent user;
SDL_SysWMEvent syswm;
} SDL_Event;
我已经导入了这样的函数:
#[link(name = "SDL2")]
extern "C" {
fn SDL_PollEvent(event: *mut SdlEvent) -> libc::c_int;
}
并宣布类似这样的类型:
type SdlEvent = [u8; 56];
现在我可以调用SDL_Pollevent
并检索联合的type
值:
// According to sizeof(SDL_Event), the unit is 56 bytes
let mut sdl_event: SdlEvent = [0; 56];
unsafe { SDL_PollEvent(&mut sdl_event) };
let event_type: u32 = u32::from_be((sdl_event[0] as u32) << 24 | (sdl_event[1] as u32) << 16 |
(sdl_event[2] as u32) << 8 |
(sdl_event[3] as u32));
match event_type {
0x100 => {
Event {
// 0x100 is SDL_QUIT -> quit application
}
}
0x200 => {
Event { // SDL_KEYDOWN
// How can I
}
}
}
这很好用,但现在我想知道哪个键被按下了,这意味着我需要检索key
类型的值SDL_KeyboardEvent
。我怎么能这样做?
答案 0 :(得分:5)
联盟基本上与C类似,这意味着它们不安全。从Rust 1.16开始,它们也是一个不稳定的特性:
#![feature(untagged_unions)]
extern crate libc;
// Definitions for SDL_ActiveEvent, SDL_KeyboardEvent, etc.
#[repr(C)]
union SDLEvent {
typ: libc::uint8_t,
active: SDL_ActiveEvent,
key: SDL_KeyboardEvent,
// All the rest
}
fn thing(event: SDLEvent) {
unsafe {
println!("{}", event.typ);
}
}