在discussing/learning about the correct way to call a FFI of the Windows-API from Rust之后,我玩得更远了一点,我想再检查一下我的理解。
我有一个被调用两次的Windows。在第一个调用中,它返回实际out参数所需的缓冲区大小。然后,它被称为第二次具有足够大小的缓冲区。我目前正在使用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 = "*"发布于 2016-09-17 20:09:43
理想情况下,您可以使用std::alloc::alloc,因为您可以指定所需的对齐作为布局的一部分。
pub unsafe fn alloc(layout: Layout) -> *mut u8主要的缺点是,您需要知道对齐,即使当您释放分配。
使用Vec作为一种简单的分配机制是一种常见的做法,但您在使用它时需要小心。
Vec分解成组件,则需要。shrink_to_fit来确保这两个值是相同的。Vec。
Vec做而不是有一个空指针!:
fn main() { let v: Vec = Vec::new();println!("{:p}",v.as_ptr());// => 0x1 }对于您的具体情况,我可能建议使用capacity of Vec而不是自己跟踪第二个变量。您将注意到在第一个调用之后忘记更新pcb_buffer,所以我非常肯定代码总是失败的。这很烦人,因为它需要一个可变的引用,所以你不能完全摆脱它。
此外,您可以只使用extend空间,而不是Vec中的reserve。
也不能保证第一次调用期间所需的大小将与第二次调用期间所需的大小相同。你可以做一些循环,但你必须担心无限循环的发生。
https://stackoverflow.com/questions/39550856
复制相似问题