cxx icon indicating copy to clipboard operation
cxx copied to clipboard

Support standard C numeric types

Open adetaylor opened this issue 4 years ago • 7 comments

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.

adetaylor avatar May 12 '21 03:05 adetaylor

Yep, I'll take a look.

adetaylor avatar May 12 '21 14:05 adetaylor

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.

adetaylor avatar May 13 '21 00:05 adetaylor

Status on this?

vurvdev avatar Nov 08 '21 04:11 vurvdev

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_std and core (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.

nathan-at-least avatar Aug 30 '22 01:08 nathan-at-least

But wait, building now works, even though I didn't replace c_char with u8! 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.

Starosielec avatar Nov 06 '23 22:11 Starosielec