-
Notifications
You must be signed in to change notification settings - Fork 339
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add CxxChar to bind to C++ char32_t type #725
base: master
Are you sure you want to change the base?
Conversation
This makes it possible to implement functions in Rust that accept a char32_t. The CxxChar type is necessary because C++ does not guarantee that char32_t contains a valid Unicode scalar value. There is not yet a way for C++ code to create a Rust char.
/// To avoid confusion with Rust's built-in char type you probably | ||
/// shouldn't import this type with `use`. Instead, write `cxx::Char`, or | ||
/// import and use `CxxChar`. | ||
pub type Char = CxxChar; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't entirely sure of the reason for these aliases, so just following the existing pattern. 🤷♂️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR! This implementation looks good. However I wonder if it's necessary to have a repr(transparent) newtype wrapper, or if we could use just u32
as the type on the Rust side? Do you have a use case where providing a wrapper type is important?
The problem with using straight fn rust_fn(ch: u32) {}
#[cxx::bridge]
pub mod ffi {
extern "Rust" {
fn rust_fn(ch: u32);
}
} ...then the generated C++ declaration will look something like this: void rust_fn(::std::uint32_t ch) noexcept; ...and uint32_t and char32_t are distinct C++ types, mangled differently. (Reference link for the IA64 ABI followed by gcc and clang.) It's not specifically important to me to provide a wrapper type, but it is important to me to be able to generate C++ function signatures compatible with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay in that case I would ask that there not be a newtype wrapper. char32_t
in the bridge should use u32
in Rust and ::std::char32_t
in C++. You can also provide a type alias for u32
as something like cxx::num::char32_t
for downstream code to use if they choose.
So just to be clear, would you expect to be able to write: fn rust_fn(ch: u32) {}
#[cxx::bridge]
pub mod ffi {
extern "Rust" {
fn rust_fn(ch: char32_t);
}
} ...and then generate a C++ declaration using |
Right. That is how the standard library and libc do C integer types. https://doc.rust-lang.org/1.50.0/std/os/raw/index.html Canonically the rust_fn implementation would be written using cxx::num::char32_t though. |
This makes it possible to implement functions in Rust that accept a
char32_t
. TheCxxChar
type is necessary because C++ does not guarantee thatchar32_t
contains a valid Unicode scalar value.There is not yet a way for C++ code to create a Rust
char
.I'll update the docs after getting feedback on the design and implementation.
Partly addresses #592.