cxx
cxx copied to clipboard
Support standard C numeric types
This adds direct support for the C integer and float types
defined in std::os::raw. Unlike existing cxx-supported integers,
these may not be a consistent length on all platforms - but sometimes
this is useful to enable direct interoperability with existing
APIs.
Yep, I'll take a look.
I added a design sketch to #682 - please take a look. It looks OK, but non-trivial, so unlikely I'll get to it especially soon. Maybe though.
Status on this?
Hi,
Prior to, or in addition to, this PR landing, is there a way to improve the docs with guidance on how to handle numeric types? Besides this table, I can't find any guidance aside from this terse sentence:
In addition to all the primitive types (i32 <=> int32_t), …
What about u8 vs char? What is c_char which seems to be in scope in the extern "Rust" section and where does that come from?
This may be something people with c++ backgrounds would know, but in c++ is std::int32_t always the same as int?
My background:
- I'm reasonably familiar with rust, whereas my c++ expertise is quite weak.
- I don't have experience with rust <-> c ffi bindings. I've read over A little C with your Rust, Rustonomicon FFI, and skimmed the libc API docs.
- Little experience with
no_stdandcore(aside from some wasm guest code experiments).
My journey: (This part is a longer narrative and hopefully useful to people thinking about improving docs.)
I want to write a rust function to parse commandline options and a config file given the int argc, char *argv[] from c++'s main.
Inside the extern "Rust" I try out this interface: fn parse_cli_and_config(argc: c_int, argv: *const *const c_char) where c_int and c_char are from use std::ffi::{c_int, c_char} in the top body (prior to #[cxx::bridge]).
This gives a cxx procmacro error (I assume) for unsupported type:
175 │ unsafe fn parse_args_and_file(argc: c_int, argv: *const *const c_char) -> Result<Config>;
│ ^^^^^ unsupported type
Fair enough.
Ok, so I remove the use std::ffi::… and I begin to replace the rust imported types. Hopefully c++ int is always i32. (I'm not certain, which is why I prefer to rely on the abstract from std::ffi.)
But wait, building now works, even though I didn't replace c_char with u8! How does that work? It isn't mentioned in the cxx API docs, AFAICT, and I am not brinding that type into scope with use. So is this somehow an implicitly defined type by cxx bridge or does it come from somewhere else?
So as it stands, I'm somewhat mystified about the primitive numeric types and which types are in scope within the #[cxx::bridge].
BTW- if this PR lands, and I could simply use the std::ffi::c_* types, the docs should also mention relying on those types if that's the recommended pattern.
But wait, building now works, even though I didn't replace
c_charwithu8! How does that work?
I also frequently see failing code going through partial builds sometimes. there seems to be some minor caching problems with partial builds. Try cargo clean and retry, “c_char” should fail.