diff --git a/crates/libs/core/src/dynamic_cast.rs b/crates/libs/core/src/dynamic_cast.rs index acedc1d697..50fa7f29a4 100644 --- a/crates/libs/core/src/dynamic_cast.rs +++ b/crates/libs/core/src/dynamic_cast.rs @@ -51,8 +51,7 @@ pub struct IDynamicCast_Vtbl { impl IDynamicCast_Vtbl { pub const fn new + Any + 'static, Impl: IDynamicCast_Impl, const OFFSET: isize>() -> Self { unsafe extern "Rust" fn as_any + 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 } diff --git a/crates/tests/implement_core/src/com_object.rs b/crates/tests/implement_core/src/com_object.rs index 13c32ce24a..c9c245b329 100644 --- a/crates/tests/implement_core/src/com_object.rs +++ b/crates/tests/implement_core/src/com_object.rs @@ -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, } @@ -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()), } @@ -110,6 +114,7 @@ impl MyApp { fn new(x: u32) -> ComObject { ComObject::new(Self { x, + signature: APP_SIGNATURE, tombstone: Arc::new(Tombstone::default()), }) } @@ -342,6 +347,7 @@ 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() }); @@ -349,7 +355,6 @@ fn to_object() { assert!(!tombstone.is_dead()); drop(app); - assert!(tombstone.is_dead()); } @@ -362,9 +367,11 @@ fn dynamic_cast() { assert!(!idyn.is::()); assert!(idyn.is::()); - let _dyn_app: &MyApp_Impl = idyn.downcast_ref::().unwrap(); + let dyn_app_ref: &MyApp_Impl = idyn.downcast_ref::().unwrap(); + assert_eq!(dyn_app_ref.signature, APP_SIGNATURE); - let _dyn_owned: ComObject = unknown.cast_impl().unwrap(); + let dyn_app_owned: ComObject = 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.