In my previous question I asked how to cast LPVOID
to LPNETRESOURCEW
. And it goes well. I have a struct of NETRESOURCEW
with fields:
dwScope: DWORD,
dwType: DWORD,
dwDisplayType: DWORD,
dwUsage: DWORD,
lpLocalName: LPWSTR,
lpRemoteName: LPWSTR,
lpComment: LPWSTR,
lpProvider: LPWSTR,
According to docs nr.lpRemoteName
is LPWSTR
-> *mut u16
. I've tried using OsString::from_wide
but nothing got well. How can I convert LPWSTR
into Rust *str
or String
and print it in console?
CodePudding user response:
This is normally done by marshalling the string pointer into a slice. First you need to get the length of the string / slice which can be done like this if the string is null-terminated:
let length = (0..).take_while(|&i| *my_string.offset(i) != 0).count();
Then you can create the slice like so
let slice = std::slice::from_raw_parts(my_string, length);
and finally convert the slice into an OsString
:
let my_rust_string = OsString::from_wide(slice).to_string_lossy().into_owned();
Update due to comment
I have verified that the given approach works as can be reproduced using this snippet:
use std::{ffi::OsString, os::windows::prelude::OsStringExt};
use windows_sys::w;
fn main() {
let my_string = w!("This is a UTF-16 string.");
let slice;
unsafe {
let length = (0..).take_while(|&i| *my_string.offset(i) != 0).count();
slice = std::slice::from_raw_parts(my_string, length);
}
let my_rust_string = OsString::from_wide(slice).to_string_lossy().into_owned();
println!("{}", my_rust_string);
}
If you get a STATUS_ACCESS_VIOLATION
it is most likely because your string is not null-terminated in which case you would need to determine the length of the string in another way or preallocate the buffer.