Info
This post is auto-generated from RSS feed The Rust Programming Language Forum - Latest topics. Source: Vector set_len and string ffi safety
I'm writing an FFI call with win32, and the function fills a string buffer:
fn get_computer_name_two_step() -> String {
let mut buff_len = 0u32;
unsafe {
// this function will return an error code because it
// did not actually write the string. This is normal.
let e = GetComputerNameW(None, &mut buff_len).unwrap_err();
debug_assert_eq!(e.code(), HRESULT::from(ERROR_BUFFER_OVERFLOW));
}
// buff len now has the length of the string (in UTF-16 characters)
// the function would like to write. This *does include* the
// null terminator. Let's create a vector buffer and feed that to the function.
let mut buffer = Vec::<u16>::with_capacity(buff_len as usize);
unsafe {
WindowsProgramming::GetComputerNameW(
Some(PWSTR(buffer.as_mut_ptr())),
&mut buff_len).unwrap();
// set the vector length
// buff_len now includes the size, which *does not include* the null terminator.
buffer.set_len(buff_len as usize + 1);
}
// we can now convert this to a valid Rust string
// omitting the null terminator
String::from_utf16_lossy(&buffer[..buff_len as usize])
}
I'm setting the vector length to include the null terminator - I know this is fine and valid, but if I'm never going to need that null terminator, is it valid instead to just set the vector's length to the length of the string (before the terminator)? So instead doing something like:
// set the vector length
// buff_len now includes the size, which *does not include* the null terminator.
// this will set the length to just before the null terminator
buffer.set_len(buff_len);
...
// return the string
String::from_utf16_lossy(&buffer)
Perhaps a better question is: "if I'm using the vector as a buffer, and I write to it, is there any harm in setting the length to less than the number of bytes written, if the bytes at the end are never used?" Or will this leak memory somehow?
Thank you for any help.
10 posts - 5 participants
🏷️ rust_feed