How to get a raw pointer to another raw pointer (Rust and FFI)?


I am writing rust bindings to MQTT and got stuck with the following problem:

// C function:
/*void MQTTAsync_freeMessage(MQTTAsync_message** message)
	printf("[libmqtt] msg ptr: %p\n", message);
	*message = NULL;

// rust binding
extern "C" fn MQTTAsync_freeMessage(msg: *mut *mut MQTTAsync_message) -> () {}

// receive callback from C lib where we have a message: 
extern "C" fn received(amessage: *mut MQTTAsync_message) -> i32 {    
    // in C: MQTTAsync_freeMessage(&amessage);
    // how to call it correctly from rust - how to get a raw pointer to a raw pointer?

    // following is wrong because amessage and amessage as *mut *mut MQTTAsync_message have the same addresses
    // it just makes it to compile, however it must be wrong because addresses must differ
    println!("ptr                : {:?}", amessage);
    println!("ptr                : {:?}", amessage as *mut *mut MQTTAsync_message);
    unsafe{MQTTAsync_freeMessage(amessage as *mut *mut MQTTAsync_message)};

Here is also playpen to play with:


&mut amessage is a pointer to amessage and is coercible to *mut *mut MQTTAsync_message. (You’ll need to make amessage mutable in the function signature or assign it to another mutable variable).



I tried before just with &, however did not know about &mut.

expected `*mut *mut MQTTAsync_message`,
found `&*mut MQTTAsync_message `
extern "C" fn received(amessage: *mut MQTTAsync_message) -> i32 {
    let mut msg = amessage;
    unsafe{MQTTAsync_freeMessage(&mut msg)};