¿Cuál es la forma correcta de asignar datos para pasar a una llamada FFI?

Despuésdiscutir / aprender sobre la forma correcta de llamar a un FFI de la API de Windows desde Rust, Jugué un poco más y me gustaría comprobar mi comprensión.

Tengo una API de Windows que se llama dos veces. En la primera llamada, devuelve el tamaño del búfer que necesitará para su parámetro de salida real. Luego, se llama por segunda vez con un búfer de tamaño suficiente. Actualmente estoy usando unVec como un tipo de datos para este búfer (ver ejemplo a continuación).

El código funciona, pero me pregunto si esta es la forma correcta de hacerlo o si sería mejor utilizar una función comoalloc::heap::allocate para reservar directamente algo de memoria y luego usartransmute para convertir el resultado del FFI de nuevo. Nuevamente, mi código funciona pero estoy tratando de mirar un poco detrás de escena.

extern crate advapi32;
extern crate winapi;
extern crate widestring;
use widestring::WideCString;
use std::io::Error as IOError;
use winapi::winnt;

fn main() {
    let mut lp_buffer: Vec<winnt::WCHAR> = Vec::new();
    let mut pcb_buffer: winapi::DWORD = 0;

    let rtrn_bool = unsafe {
        advapi32::GetUserNameW(lp_buffer.as_mut_ptr(),
                               &mut pcb_buffer )
    };

    if rtrn_bool == 0 {

        match IOError::last_os_error().raw_os_error() {
            Some(122) => {
                // Resizing the buffers sizes so that the data fits in after 2nd 
                lp_buffer.resize(pcb_buffer as usize, 0 as winnt::WCHAR);
            } // This error is to be expected
            Some(e) => panic!("Unknown OS error {}", e),
            None => panic!("That should not happen"),
        }
    }


    let rtrn_bool2 = unsafe {
        advapi32::GetUserNameW(lp_buffer.as_mut_ptr(), 
                               &mut pcb_buffer )
    };

    if rtrn_bool2 == 0 {
        match IOError::last_os_error().raw_os_error() {
            Some(e) => panic!("Unknown OS error {}", e),
            None => panic!("That should not happen"),
        }
    }

    let widestr: WideCString = unsafe { WideCString::from_ptr_str(lp_buffer.as_ptr()) };

    println!("The owner of the file is {:?}", widestr.to_string_lossy());
}

Dependencias:

[dependencies]
advapi32-sys = "0.2"
winapi = "0.2"
widestring = "*"

Respuestas a la pregunta(2)

Su respuesta a la pregunta