Skip to content

Commit

Permalink
zomg pointers
Browse files Browse the repository at this point in the history
  • Loading branch information
Arlie Davis committed May 23, 2024
1 parent 6e1dd67 commit 6cfa34f
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 5 deletions.
3 changes: 1 addition & 2 deletions crates/libs/core/src/dynamic_cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@ pub struct IDynamicCast_Vtbl {
impl IDynamicCast_Vtbl {
pub const fn new<Identity: IUnknownImpl<Impl = Impl> + Any + 'static, Impl: IDynamicCast_Impl, const OFFSET: isize>() -> Self {
unsafe extern "Rust" fn as_any<Identity: IUnknownImpl<Impl = Impl> + Any + 'static, Impl: IDynamicCast_Impl, const OFFSET: isize>(this: *mut c_void) -> *const dyn Any {
let this_inner = (this as *mut *mut c_void).offset(OFFSET) as *mut Impl; // <-- this is the "inner" object pointer, e.g. MyApp
let this_outer = this_inner.sub(Identity::INNER_OFFSET_IN_POINTERS) as *const Identity; // <-- this is the "outer" object pointer, e.g. MyApp_Impl
let this_outer = (this as *mut *mut c_void).offset(OFFSET) as *mut Identity; // <-- this is the "outer" object pointer, e.g. MyApp_Impl
let outer_any: &dyn Any = &(*this_outer); // <-- this cast works because of the + Any + 'static constraints
outer_any as *const dyn Any
}
Expand Down
13 changes: 10 additions & 3 deletions crates/tests/implement_core/src/com_object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ unsafe trait IBar: IUnknown {
fn say_hello(&self);
}

const APP_SIGNATURE: [u8; 8] = *b"cafef00d";

#[implement(IFoo, IBar, IDynamicCast)]
struct MyApp {
signature: [u8; 8],
x: u32,
tombstone: Arc<Tombstone>,
}
Expand Down Expand Up @@ -64,6 +67,7 @@ impl core::fmt::Display for MyApp {
impl Default for MyApp {
fn default() -> Self {
Self {
signature: APP_SIGNATURE,
x: 0,
tombstone: Arc::new(Tombstone::default()),
}
Expand Down Expand Up @@ -110,6 +114,7 @@ impl MyApp {
fn new(x: u32) -> ComObject<Self> {
ComObject::new(Self {
x,
signature: APP_SIGNATURE,
tombstone: Arc::new(Tombstone::default()),
})
}
Expand Down Expand Up @@ -342,14 +347,14 @@ fn to_object() {

let second_app = app_outer.to_object();
assert!(!tombstone.is_dead());
assert_eq!(second_app.signature, APP_SIGNATURE);

println!("x = {}", unsafe { second_app.get_x() });

drop(second_app);
assert!(!tombstone.is_dead());

drop(app);

assert!(tombstone.is_dead());
}

Expand All @@ -362,9 +367,11 @@ fn dynamic_cast() {
assert!(!idyn.is::<SendableThing>());
assert!(idyn.is::<MyApp>());

let _dyn_app: &MyApp_Impl = idyn.downcast_ref::<MyApp>().unwrap();
let dyn_app_ref: &MyApp_Impl = idyn.downcast_ref::<MyApp>().unwrap();
assert_eq!(dyn_app_ref.signature, APP_SIGNATURE);

let _dyn_owned: ComObject<MyApp> = unknown.cast_impl().unwrap();
let dyn_app_owned: ComObject<MyApp> = unknown.cast_impl().unwrap();
assert_eq!(dyn_app_owned.signature, APP_SIGNATURE);
}

// This tests that we can place a type that is not Send in a ComObject.
Expand Down

0 comments on commit 6cfa34f

Please sign in to comment.