使用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()
}