Jump to content

Passing a UTF-16 string to C from Rust

Breadpudding

https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html#using-extern-functions-to-call-external-code

https://locka99.gitbooks.io/a-guide-to-porting-c-to-rust/content/features_of_rust/types.html

 

u16 in Rust is not a string, it's an unsigned 16bit integer (or more conveniently a uint16_t from stdint.h). If you want to pass a string from Rust to C read this:

https://stackoverflow.com/a/24148033/4153995

Don't ask to ask, just ask... please 🤨

sudo chmod -R 000 /*

Link to comment
Share on other sites

Link to post
Share on other sites

18 hours ago, Sauron said:

u16 in Rust is not a string, it's an unsigned 16bit integer (or more conveniently a uint16_t from stdint.h).

Let me explain. Each character is 16 bits wide since that's what UEFI wants(hence the u16). C had a simple way of doing this by simply appending a string with the letter L. With Rust however, it seems to be more complicated as it doesn't seem to have UTF-16 support out of the box. What I'm trying to figure out is how I can turn a Unicode string into a pointer to an array of 16 bit characters.

Discord: Breadpudding#9078

GitHub: https://github.com/cbpudding

Programming Guild: https://discord.gg/7ZVbxXT

Link to comment
Share on other sites

Link to post
Share on other sites

6 hours ago, Breadpudding said:

What I'm trying to figure out is how I can turn a Unicode string into a pointer to an array of 16 bit characters.

Does passing a *const u16 not work? If not what does the compiler say?

Don't ask to ask, just ask... please 🤨

sudo chmod -R 000 /*

Link to comment
Share on other sites

Link to post
Share on other sites

I haven't used it personally, but it looks like the widestring crate might help you - https://crates.io/crates/widestring. With that crate, based on the docs you would do

use widestring::{U16CString, U16CStr};

// Constructing a UTF-16 string from a Rust &str is straight forward. This creates an owned U16String
let s = U16CString::from_str("Whatever regular Rust string you want to send").unwrap();
// If you need a pointer to it to use for FFI, I believe you would use
let ptr: *const u16 = s.as_ptr();
// *const u16 is equivalent to the C type *wchar_t (as long as wchar_t is UTF-16)

// If you're given *wchar_t (call it p), you can convert it into an &U16CStr (nb not an owned U16CString) using
let s = unsafe {
  U16CStr::from_ptr_str(p)
};
// Be careful with lifetimes, because the lifetime of the returned value will be unchecked.

 

HTTP/2 203

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×