How can I access values from a C union in Rust?

Philipp Ludwig

I'm trying to call the function SDL_PollEvent from the C library SDL2. I'm aware that there are already wrappers available, but I'd like to create my own, just for learning. The function expects a pointer to this C union:

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;

I have imported the function like this:

#[link(name = "SDL2")]
extern "C" {
    fn SDL_PollEvent(event: *mut SdlEvent) -> libc::c_int;
} 

And declared the type like this:

type SdlEvent = [u8; 56];                                                    

Now I can call SDL_Pollevent and retrieve the type value of the union:

// 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 
     }
    }                                      
}

This works fine, but now I'd like to know which key has been pressed, which means I need to retrieve the value key of the type SDL_KeyboardEvent. How can I do this?

Shepmaster

Unions are basically exactly like C, which means they are unsafe to access. They are also an unstable feature as of 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);
    }
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How can I create enums with constant values in Rust?

How can I access the RGB values of a UIColor?

How can I access a C global variable/constant in Rust FFI?

How do I access a zero-terminated array of function pointers declared in C from Rust?

How I can I lazily read multiple JSON values from a file/stream in Rust?

How can I access macOS API calls from C on Mac?

Can I derive values from a union type to create new union type?

How can I keep the order of column values in a union select?

How do I substract values from an UNION query in POSTGRESQL?

Why can I not access this Rust simple server from the Internet?

How can I make a range of values using BigInt or BigUint in Rust?

How can I access a global C array of structs from a Rust library?

How do I a union type of string values from an enum?

C How can i access values in misaligned memory

How can i access a listbox from another pc in C#

How do I use the constructors in a named union? And how can I change the values in the same union instance later? c++/c++11

In F#, How can I attach metadata to discriminated union values?

How can I access the values in this NSDictionary in Swift?

How can I access particular column values?

How can I access values in this JSON?

Can I access a union in my source.c from main.c in PIC C18?

How can I get specific values from JObject in c#

How can I extract values from double[,] in C#?

How I can access to these values in body question,

How can I await on HashMap future values in rust?

How can I get distinct values from two tables using union?

How can I achieve a union type of object values in typescript

How can I access values in another class inherited from public class C#?

How can I access a nested discriminated union value?