¿Por qué todas mis punteros apuntando al mismo lugar con to_c_str() en rust?

StackOverflow https://stackoverflow.com//questions/23053398

  •  22-12-2019
  •  | 
  •  

Pregunta

Tengo este óxido método:

/* Define a python method on a given module */
pub fn method(data: *mut Struct_ppyData, module: ~str, method: ~str, callback: PyCFunction, flags: Method, help: ~str) {
  let mbytes = module.to_c_str().with_mut_ref(|a: * mut c_char| { a });
  let fbytes = method.to_c_str().with_mut_ref(|b: * mut c_char| { b });
  let dbytes = help.to_c_str().with_mut_ref(|c: * mut c_char| { c });
  println!("Incoming! {} {} {}\n", module, method, help);
  println!("Invoking! {} {} {}\n", mbytes, fbytes, dbytes);
  let cflags = flags as c_int;
  unsafe {
    ppy_method(data, mbytes, fbytes, callback, cflags, dbytes);
  }
}

Y la salida que se obtiene es:

Incoming! yyy xxx A callback.
Invoking! 0x7f85084077d0 0x7f85084077d0 0x7f85084077d0

Qué?Eso es lo que la ffi c llame ve también:

Received a value
Pointer: 7f85084077d0
length: 11
 --------> value: A callback.
Received a value
Pointer: 7f85084077d0
length: 11
 --------> value: A callback.
Received a value
Pointer: 7f85084077d0
length: 11
 --------> value: A callback.

¿Por qué en la tierra son los valores de mb, fbytes y dbytes todos el mismo?O_o

¿Fue útil?

Solución

Lo que están haciendo es peligroso, y es que puedas tropezar.

module.to_c_str() asigna espacio para un CString.Llamar with_mut_ref en que da una inseguro puntero (*T o *mut T) para que CString—pero que *mut c_char sólo es válido para el cierre que se pasen.Usted la ha mantenido con vida más allá del final del clausura, y así, todas las apuestas están apagadas;como es, la CString se libera inmediatamente después de que la expresión, porque no se almacena en cualquier lugar.En consecuencia, usted tiene un colgando inseguro puntero (*T se llama inseguro por una razón!).A continuación, la siguiente línea que va hacer una partida similar, y he aquí!es en el mismo lugar.Resultado final:tres idénticos a los punteros, todos apuntando a la misma basura de datos.

Lo que usted debe hacer en su lugar, si de hecho necesita de una inseguro puntero, es el nido de las cosas.

También, como se observa en la dbaupp, usted no necesita tomar posesión de las cadenas;usted podría utilizar &str en lugar de ~str.

/// Define a python method on a given module
pub fn method(data: *mut Struct_ppyData, module: &str, method: &str,
              callback: PyCFunction, flags: Method, help: &str) {
    module.to_c_str().with_mut_ref(|mbytes| {
        method.to_c_str().with_mut_ref(|fbytes| {
            help.to_c_str().with_mut_ref(|dbytes| {
                println!("Incoming! {} {} {}\n", module, method, help);
                println!("Invoking! {} {} {}\n", mbytes, fbytes, dbytes);
                let cflags = flags as c_int;
                unsafe {
                    ppy_method(data, mbytes, fbytes, callback, cflags, dbytes);
                }
            })
        })
    })
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top