Skip to content

Commit

Permalink
Implement Deref for COM interface hierarchies defined with the `int…
Browse files Browse the repository at this point in the history
…erface` macro (#2969)
  • Loading branch information
kennykerr authored Apr 4, 2024
1 parent 16792d5 commit f4be25d
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 1 deletion.
7 changes: 6 additions & 1 deletion crates/libs/interface/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,12 @@ impl Interface {
const IID: ::windows_core::GUID = #guid;
}
impl ::windows_core::RuntimeName for #name {}

impl ::std::ops::Deref for #name {
type Target = #parent;
fn deref(&self) -> &Self::Target {
unsafe { ::std::mem::transmute(self) }
}
}
#com_trait
#vtable
#conversions
Expand Down
56 changes: 56 additions & 0 deletions crates/tests/interface/tests/deref.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#![allow(non_snake_case)]

use windows_core::*;

#[interface("7e75ffe0-2f8c-4040-953e-b1f83a48f77b")]
unsafe trait IFirst: IUnknown {
unsafe fn First(&self) -> i32;
}

#[interface("fe43afb2-43a1-45f9-adbb-1079b410cb9a")]
unsafe trait ISecond: IFirst {
unsafe fn Second(&self) -> i32;
}

#[interface("4b8c8b47-32dd-4aba-8c68-b0d14703b845")]
unsafe trait IThird: ISecond {
unsafe fn Third(&self) -> i32;
}

#[implement(IFirst, ISecond, IThird)]
struct Class;

impl IFirst_Impl for Class {
unsafe fn First(&self) -> i32 {
1
}
}

impl ISecond_Impl for Class {
unsafe fn Second(&self) -> i32 {
2
}
}

impl IThird_Impl for Class {
unsafe fn Third(&self) -> i32 {
3
}
}

#[test]
fn test() {
unsafe {
let third: IThird = Class.into();
assert_eq!(third.First(), 1);
assert_eq!(third.Second(), 2);
assert_eq!(third.Third(), 3);

let second: ISecond = third.cast().unwrap();
assert_eq!(second.First(), 1);
assert_eq!(second.Second(), 2);

let first: IFirst = third.cast().unwrap();
assert_eq!(first.First(), 1);
}
}

0 comments on commit f4be25d

Please sign in to comment.