Comments (6)
I've encountered this in my work codebase as well. What we've done for now is declare RawOptionalBaseValue as an opaque C type in both files, and then do unsafe pointer casts from one to the other where necessary:
// :(
fn convert(bv: &mut first::ffi::BaseValue) -> &mut second::ffi::BaseValue {
unsafe {
&mut *(bv as *mut first::ffi::BaseValue as *mut second::ffi::BaseValue)
}
}
Obviously I'd like to support this better. It needs some more design work but I have some ideas for how to make it work safely and seamlessly, based on treating opaque C types in a way that doesn't produce a distinguishable representation in different places when using the same header and type name:
// effectively this, but encoded without relying on const generics
type RawOptionalBaseValue = OpaqueC<"base/values_rust.h", "RawOptionalBaseValue">;
from cxx.
The part that needs design work is how to deal with codebases in which the same import path might not always refer to the same exact file; in that case allowing the interconversion would be bad. I'm confident it's solvable but just needs some attention.
from cxx.
Thanks, your workaround worked nicely for me.
from cxx.
Does anyone know how bindgen deals with the same issue? If we do two bindgen invocations in two different crates but some of the types are in common (something like folly::StringPiece which both crates might use) then do they also have the problem of those becoming two incompatible StringPiece types on the Rust side?
I guess they provide a workaround of --opaque-type folly::StringPiece
which turns it into pub type folly_StringPiece = [u64; 2usize]
which is the same type in every crate, but it's not great because it's also the same type as lots of other non-StringPiece types.
from cxx.
I got a chance to think about this a bit today. I think what I'd like looks more or less like this:
// basevalue.rs
#[cxx::bridge(namespace = base)]
pub mod ffi {
extern "C" {
include!("base/values_rust.h");
type RawOptionalBaseValue;
fn /* ... */
}
}
// json.rs
#[cxx::bridge(namespace = base)]
pub mod ffi {
extern "C" {
type RawOptionalBaseValue = basevalue::ffi::RawOptionalBaseValue;
fn /* ... */
}
}
where the first type
expands to something like:
// same as today
#[repr(C)]
pub struct RawOptionalBaseValue {
_private: ::cxx::private::Opaque,
}
// new
unsafe impl ::cxx::private::ExternType for RawOptionalBaseValue {
type Id = /*type-encoding of "base::RawOptionalBaseValue"*/;
}
while the second type
expands to something like:
// assume that they're the same
pub use basevalue::ffi::RawOptionalBaseValue as RawOptionalBaseValue;
// but also enforce that they're the same at compile time
const _: fn() = ::cxx::private::enforce_extern_type_id::<
RawOptionalBaseValue,
/*type-encoding of "base::RawOptionalBaseValue"*/,
>;
and in CXX we provide:
#[doc(hidden)]
pub fn enforce_extern_type_id<T: ExternType<Id = Id>, Id>() {}
The exact type-encoding there for the strings isn't important and I am not particularly worried about figuring out something that will work. Longer term we'll use a "non-type template parameter" a.k.a. "const generic" with the actual string literal, but for now you can conceptualize a possible encoding as:
"ABC"
<->ch::A<ch::B<ch::C>>
where each of those is a distinct struct A<Rest = ()>(PhantomData<Rest>)
. This wouldn't necessarily be how we do it for various reasons but it gives the same effect.
from cxx.
In fact we'd likely end up making the trait ExternType
public (but still unsafe) so that the user can write their own impls for any bindgen-generated types to let those interop seamlessly with cxx bridge extern functions.
unsafe impl cxx::ExternType for folly_sys::StringPiece {
type Id = cxx::type_id!("folly::StringPiece");
}
from cxx.
Related Issues (20)
- Question: estimate workload to call functions from geogram HOT 1
- Returning `CxxString` from Rust to C++ HOT 5
- Extern C++ Enums HOT 5
- Advice/example on docs.rs strategy HOT 2
- Feature Request: Add support for nested Vector types HOT 1
- Building two CXX C++ bindings with the same symbols but in different namespaces. HOT 2
- Including bridge from another crate
- Error in configuring crates_universe when included as a Bazel module HOT 6
- Error compiling `cxx.cc` on Windows HOT 1
- Proposal: implementing native C++ std::error_code
- Link failure when using CXX-backed function from another crate HOT 1
- Unsupported element type of Vec<[u64; 3]>
- How to include C++ files whose directory is given by an environment variable? HOT 1
- Error compiling demo to wasm on macOS HOT 5
- Is there a way to expose a C++ class that is itself a wrapper on `std::shared_ptr`?
- How can I `include!` a file in OUT_DIR
- How can I return a vector of non-trivial type of C++ to Rust?
- LNK2019 unresolved symbol for Vec<SharedStruct> using MSVC
- Using CXX in multiple DLLs always results in undefined behavior?
- Does the core safety claim need rephrasing? HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cxx.