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


#1

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


// C function:
/*void MQTTAsync_freeMessage(MQTTAsync_message** message)
{
	FUNC_ENTRY;
	printf("[libmqtt] msg ptr: %p\n", message);
	free((*message)->payload);
	free(*message);
	*message = NULL;
	FUNC_EXIT;
}*/

// 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)};
    1
}

Here is also playpen to play with: http://is.gd/S3r61l


#2

&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).


#3

Thanks.

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)};
    1
}