google / google/autocxx

Field access to opaque types

Open
#53 1 comment 3 reactions 0 assignees View on GitHub
cpp-feature
Dominant language
Rust
Stars
2.6k
Forks
175
PR merge metrics
No merged PRs in 30d

Description

There are some C++ types where `autocxx` just says "nope, we can't pass it by value" - `autocxx` calls these non-POD types; `cxx` calls them `Opaque` (see #17 for the terminology difference).

For those, `autocxx` offers no means to access the fields.

Rust cannot and should not attempt to access those fields, because we can't know the correct offsets. It's my intention that we should autogenerate accessor methods. Specifically, here's what I think we need to do.

1. For any non-POD type, when we discover the fields as output by bindgen, add a new type of `AdditionalNeed` to add an accessor method - https://github.com/google/autocxx/blob/main/engine/src/additional_cpp_generator.rs#L101. (Possibly we just want to do this for public fields or similar; I haven't checked if that information is exposed by bindgen or if it can be configured using bindgen options).
2. Generate a getter method with some plausible name within `additional_cpp_generator.rs`.
3. This will automatically be picked up during the second invocation of `bindgen` within autocxx, and therefore we'll get Rust bindings to this method within our `ffi::cxxbridge` generated code.
4. Now, make it work for fields which we can't safely pass by value because _those fields themselves_ are non-POD types, e.g. `std::string`. One option here is to do a _third_ pass of bindgen, which would replace `fn thingy_getter(thingy: &Thingy) -> CxxString` automatically with `fn thingy_getter(thingy: &Thingy) -> UniquePtr` and all would be well. But we don't really want to run bindgen three times... it's slow. So it would probably be better to add knowledge of these cases into `additional_cpp_generator.rs` itself.
5. Do setters as well.
6. Add syntactic sugar so it's less obvious that we're calling a method to get or set the field. I'm not sure how best to do this. #37 is in the area, as is #31.
7. Replicate this getting/setting syntax for POD types, where it will boil down to a direct field access in pure Rust, but with identical syntax.
8. Out of curiosity, see whether the generated assembly code is actually the same when cross-language LTO is used (see #52).

Contributor guide

Open the contributing guide

Research direction

Start with engine/src/additional_cpp_generator.rs and the existing AdditionalNeed handling, then trace the second bindgen invocation. Review #17, #31, #37, and #52 for terminology and related syntax or LTO considerations. Done means generated accessors support opaque fields, including non-POD fields, with getters, setters, and matching syntax for POD types.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, rust
Domain
devtools, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.