microsoft / windows-rs

Rust for Windows
https://kennykerr.ca/rust-getting-started/
Apache License 2.0
10.36k stars 486 forks source link

Dynamic casting to COM implementation #3055

Closed sivadeilra closed 4 months ago

sivadeilra commented 4 months ago

This provides a new feature for COM developers using the windows-rs crate. It allows for safe dynamic casting from IUnknown to an implementation object. It is based on Rust's Any trait.

Any type that is marked with #[implement], except for those that contain non-static lifetimes, can be used with dynamic casting.

Example:

#[implement(IFoo)]
struct MyApp { ... }

fn main() {
    let my_app = ComObject::new(MyApp { ... });
    let iunknown: IUnknown = my_app.to_interface();
    do_stuff(&iunknown);
}

fn do_stuff(unknown: &IUnknown) -> Result<()> {
    let my_app: ComObject<MyApp> = unknown.cast_object()?;
    my_app.internal_method();
    Ok(())
}
kennykerr commented 4 months ago

As discussed offline, we can extend the identity vtable pointer such that IDynamicCast inherits from IInspectable so that the instance size remains the same and ideally optimize interlocked cost as appropriate.

https://github.com/microsoft/windows-rs/blob/40d35fabf553a63c577969e70b4e0ff70e4e11c6/crates/libs/implement/src/lib.rs#L132