Alocando um Objeto para Chamadas de Biblioteca C / FFI
Eu tenho uma biblioteca C, que tem implementação gpio. Há gpio_type que é alvo específico, cada MCU tem uma definição diferente para gpio_type. Uma das funções na biblioteca:
void gpio_init(gpio_type *object, int32_t pin);
Quero escrever a abstração do objeto Gpio no Rust, usando as funções da biblioteca C. Portanto, precisa de algo como o tipo de ponteiro opaco (em C ++, eu apenas criaria uma variável de membro com o tipo: gpio_type). Imaginei que criaria um enum (ou struct) vazio, alocaria um espaço necessário para o objeto e transmutaria para corresponder ao tipo na camada 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
}
}
}
Isso tem como alvo dispositivos incorporados, portanto, sem std, sem libc. Eu não quero redefinir gpio_type para cada destino enferrujado (copie a declaração C para cada destino), procurando algo que apenas aloque memória para o objeto que C manipulará.
O seguinte trecho abaixo produz um ponteiro para o endereço 0 de acordo com a desmontagem. Desmontagem para o novo método 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}
Alguma idéia de por que 462 é 0?