In your situation, you should always have a maximum of 255 bytes, so you can use an array instead of a vector. This reduces the entire template to a call to mem::uninitialized() , a call to as_mut_ptr() and a cut operation.
unsafe { let mut v: [u16; 255] = mem::uninitialized(); let read_len = user32::GetWindowTextW( handle as winapi::HWND, v.as_mut_ptr(), 255, ); String::from_utf16_lossy(&v[0..read_len]) }
If you want to use Vec , itβs easier there than to destroy vec and recreate it. You can write directly to Vec content and let Rust handle the rest.
let mut v: Vec<u16> = Vec::with_capacity(255); unsafe { let read_len = user32::GetWindowTextW( handle as winapi::HWND, v.as_mut_ptr(), v.capacity(), ); v.set_len(read_len); // this is undefined behavior if read_len > v.capacity() String::from_utf16_lossy(&v) }
As a side note, Rust is idiomatic not to use return in the last statement in a function, but just to let the expression stand there without a semicolon. In the source code, the final if-expression can be written as
if read_len > 0 { String::from_utf16_lossy(Vec::from_raw_parts(p, read_len as usize, cap).as_slice()) } else { "".to_string() }
but I removed all the condition from my samples, since there is no need to handle characters 0 other than characters n .
source share