Asignación de un objeto para llamadas de biblioteca C / FFI
Tengo una biblioteca C, que tiene implementación de gpio. Hay gpio_type que es específico del objetivo, cada MCU tiene una definición diferente para gpio_type. Una de las funciones en la biblioteca:
void gpio_init(gpio_type *object, int32_t pin);
Quiero escribir la abstracción del objeto Gpio en Rust, usando las funciones de la biblioteca C. Por lo tanto, necesito algo como el tipo de puntero opaco (en C ++ simplemente crearía una variable miembro con tipo: gpio_type). Pensé que iba a crear una enumeración vacía (o estructura), asignar un espacio necesario para el objeto y transmutarlo para que coincida con el tipo en la capa C.
pub enum gpio_type {}
#[link(name = "gpio_lib", kind = "static")]
extern {
pub fn gpio_init(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 for one target, will be changed later to obtain it dynamically
let gpio_out = Gpio { gpio: transmute(gpio_ptr)};
gpio_init(gpio_out.gpio, pin);
gpio_out
}
}
}
Esto apunta a dispositivos integrados, por lo tanto, no std, no libc. No quiero redefinir gpio_type para cada objetivo en óxido (copie la declaración de C para cada objetivo), buscando algo para simplemente asignar memoria para el objeto que C manejará.
El siguiente fragmento a continuación produce un puntero a la dirección 0 de acuerdo con el desmontaje. Desmontaje para el nuevo método de Gpio:
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}
¿Alguna idea de por qué 462 es 0?