Implement `Deref` for COM interface hierarchies defined with the `interface` macro (#2969)

This commit is contained in:
Kenny Kerr 2024-04-04 12:03:23 -05:00 коммит произвёл GitHub
Родитель 16792d527b
Коммит f4be25df21
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
2 изменённых файлов: 62 добавлений и 1 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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);
}
}