在学习了如何正确地从Rust中调用Windows API的FFI之后,我进一步尝试并想要确认我的理解。
我有一个被调用两次的Windows API。在第一次调用时,它会返回实际输出参数所需的缓冲区大小。然后,使用具有足够大小的缓冲区再次调用它。我目前使用
代码可以运行,但我想知道是否这是正确的做法,或者是否更好地利用像
我有一个被调用两次的Windows API。在第一次调用时,它会返回实际输出参数所需的缓冲区大小。然后,使用具有足够大小的缓冲区再次调用它。我目前使用
Vec
作为此缓冲区的数据类型(请参见下面的示例)。代码可以运行,但我想知道是否这是正确的做法,或者是否更好地利用像
alloc::heap::allocate
这样的函数直接保留一些内存,然后使用transmute
将FFI的结果转换回来。同样,我的代码可以工作,但我正在尝试看一下背后的情况。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());
}
依赖项:
[dependencies]
advapi32-sys = "0.2"
winapi = "0.2"
widestring = "*"