Skip to content

Instantly share code, notes, and snippets.

@0xc0170
Last active August 29, 2015 14:14
Show Gist options
  • Select an option

  • Save 0xc0170/e8cc0596a7f99e8c2a61 to your computer and use it in GitHub Desktop.

Select an option

Save 0xc0170/e8cc0596a7f99e8c2a61 to your computer and use it in GitHub Desktop.
Rust - allocate space for C object

C library - gpio_lib. Higher layer allocates objects, usually ObjC or c++. gpio_type is target specific, so each MCU has different definition for gpio_type.

void gpio_write(gpio_type *object, int32_t pin);

I want to write abstraction of Gpio object n Rust, using C library calls. Therefore need something like opaque pointer type, which will be known at the run time (currently just set to 4 bytes). This targets embedded devices, therefore no std, no libc. I don't want to redefine gpio_type for each target in rust (copy the C declaration for each target), looking for something to just allocate memory for the object.

pub enum gpio_type {}

#[link(name = "gpio_lib", kind = "static")]
extern {
    pub fn gpio_write(obj: *mut gpio_type, value: i32);
}

pub struct Gpio {
    gpio : *mut gpio_type,
}

impl Gpio {
    pub fn new(pin: u32) -> Gpio {
        unsafe {
            let mut gpio_ptr : &'static [u8; 4] = init(); // size of gpio in C is 4 bytes
            let gpio_out = Gpio { gpio: transmute(gpio_ptr)};
            gpio_write(gpio_out.gpio, pin);
            gpio_out
        }
    }
}

The following snippet below produces pointer to address 0 according to disassembly. Disassembly for Gpio new method:

     45c:	b580      	push	{r7, lr}
     45e:	466f      	mov	r7, sp
     460:	4601      	mov	r1, r0
     462:	2000      	movs	r0, #0
     464:	f000 fae6 	bl	a34 <gpio_init>
     468:	2000      	movs	r0, #0
     46a:	bd80      	pop	{r7, pc}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment