Was ist der richtige Weg, um Daten zuzuweisen, die an einen FFI-Anruf weitergeleitet werden sollen?

Nach diskutieren / lernen, wie man ein FFI der Windows-API von Rust richtig aufruft, Ich habe ein bisschen weiter damit gespielt und möchte mein Verständnis noch einmal überprüfen.

Ich habe eine Windows-API, die zweimal aufgerufen wird. Beim ersten Aufruf wird die Größe des Puffers zurückgegeben, der für den tatsächlichen Ausgangsparameter benötigt wird. Dann wird es ein zweites Mal mit einem Puffer von ausreichender Größe aufgerufen. Ich benutze gerade einVec als Datentyp für diesen Puffer (siehe Beispiel unten).

Der Code funktioniert, aber ich frage mich, ob dies der richtige Weg ist, oder ob es besser wäre, eine Funktion wie @ zu verwendealloc::heap::allocate, um direkt etwas Speicherplatz zu reservieren und dann @ zu verwendtransmute, um das Ergebnis vom FFI zurück zu konvertieren. Wieder funktioniert mein Code, aber ich versuche, ein bisschen hinter die Kulissen zu schauen.

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

Abhängigkeiten:

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

Antworten auf die Frage(4)

Ihre Antwort auf die Frage