Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用OsString调用winapi并转换回字符串_Winapi_Rust - Fatal编程技术网

使用OsString调用winapi并转换回字符串

使用OsString调用winapi并转换回字符串,winapi,rust,Winapi,Rust,我正在努力调用宽字符版本的GetUserName。UTF-8调用可以工作,但可能有更好的方法: #[cfg(windows)] extern crate advapi32; #[cfg(windows)] extern crate winapi; use std::ffi::CString; fn get_user_name() -> String { let mut sz: u32 = 64; unsafe { let mut username = C

我正在努力调用宽字符版本的
GetUserName
。UTF-8调用可以工作,但可能有更好的方法:

#[cfg(windows)] extern crate advapi32;
#[cfg(windows)] extern crate winapi;

use std::ffi::CString;

fn get_user_name() -> String {
    let mut sz: u32 = 64;
    unsafe {
        let mut username = CString::from_vec_unchecked(vec![0; sz as usize]);
        let ptr = username.into_raw();
        advapi32::GetUserNameA(ptr as *mut i8, &mut sz as *mut u32);
        CString::from_raw(ptr).to_str().unwrap().to_owned()
    }
}
然后我尝试了UTF-16版本。这是可行的,但看起来是错误的,因为我必须为
OsStr::new()
:

关于堆栈溢出,Rust还创建了一个字符串以传递到函数中(例如,
MessageBoxW
),但对于大小由Windows决定的情况,Rust都不需要分配空间,以便以后填充


在Rust必须预先分配缓冲区,然后(最终)转换回标准UTF-8字符串的Windows上调用宽字符函数的正确方法是什么?

从注释直接使用
Vec
是最简单的方法

fn get_user_name() -> String {
    // for windows
    let mut sz: u32 = 64;
    let mut username: Vec<u16> = vec![0; sz as usize];
    unsafe {
        advapi32::GetUserNameW(username.as_mut_ptr() as *mut u16, &mut sz as *mut u32);
    }
    String::from_utf16(&username[..sz as usize]).unwrap()
}
fn获取用户名称()->字符串{
//窗户
设mut sz:u32=64;
让mut用户名:Vec=Vec![0;sz as usize];
不安全{
advapi32::GetUserNameW(username.as_mut_ptr()as*mut u16,&mut sz as*mut u32);
}
字符串::from_utf16(&username[…sz as usize])。展开()
}

我将直接从
Vec
/
Vec
分配(或堆栈上的数组…)传递缓冲区;填充后将其转换为字符串。@Ronnie请将答案作为正确答案发布,谢谢。您这样问,人们会希望您记住答案。@Shepmaster由于某种原因没有出现在搜索中。如果您愿意,请删除此问题。感谢此代码无法检查
GetUserNameW
的返回值,因此非常不安全。
fn get_user_name() -> String {
    // for windows
    use std::ffi::OsStr;
    let mut sz: u32 = 64;
    let mut username = OsString::with_capacity(sz as usize)
        .as_os_str()
        .encode_wide()
        .collect::<Vec<u16>>();
    unsafe {
        advapi32::GetUserNameW(username.as_mut_ptr() as *mut u16, &mut sz as *mut u32);
    }
    String::from_utf16(&username[..sz as usize]).unwrap()
}
fn get_user_name() -> String {
    // for windows
    let mut sz: u32 = 64;
    let mut username: Vec<u16> = vec![0; sz as usize];
    unsafe {
        advapi32::GetUserNameW(username.as_mut_ptr() as *mut u16, &mut sz as *mut u32);
    }
    String::from_utf16(&username[..sz as usize]).unwrap()
}