usesuper::*; use core::ffi::c_void; use core::ptr::NonNull;
/// All COM interfaces (and thus WinRT classes and interfaces) implement /// [IUnknown](https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nn-unknwn-iunknown) /// under the hood to provide reference-counted lifetime management as well as the ability /// to query for additional interfaces that the object may implement. #[repr(transparent)] pubstruct IUnknown(NonNull<c_void>);
impl Drop for IUnknown { fn drop(&mutself) { unsafe {
(self.vtable().Release)(core::mem::transmute_copy(self));
}
}
}
impl PartialEq for IUnknown { fn eq(&self, other: &Self) -> bool { // First we test for ordinary pointer equality. If two COM interface pointers have the // same pointer value, then they are the same object. This can save us a lot of time, // since calling QueryInterface is much more expensive than a single pointer comparison. // // However, interface pointers may have different values and yet point to the same object. // Since COM objects may implement multiple interfaces, COM identity can only // be determined by querying for `IUnknown` explicitly and then comparing the // pointer values. This works since `QueryInterface` is required to return // the same pointer value for queries for `IUnknown`. self.as_raw() == other.as_raw()
|| self.cast::<IUnknown>().unwrap().0 == other.cast::<IUnknown>().unwrap().0
}
}
/// The `#[implement]` macro generates implementations of this trait for the types /// that it generates, e.g. `MyApp_Impl`, /// /// `ComObject` uses this trait to interact with boxed COM objects. #[doc(hidden)] pubtrait IUnknownImpl { /// The contained user type, e.g. `MyApp`. Also known as the "inner" type. typeImpl;
/// Get a reference to the backing implementation. fn get_impl(&self) -> &Self::Impl;
/// Get a mutable reference to the contained (inner) object. fn get_impl_mut(&mutself) -> &mutSelf::Impl;
/// Consumes the box and returns the contained (inner) object. This is the opposite of `new_box`. fn into_inner(self) -> Self::Impl;
/// The classic `QueryInterface` method from COM. /// /// # Safety /// /// This function is safe to call as long as the interface pointer is non-null and valid for writes /// of an interface pointer. unsafefn QueryInterface(&self, iid: *const GUID, interface: *mut*mut c_void) -> HRESULT;
/// Increments the reference count of the interface fn AddRef(&self) -> u32;
/// Decrements the reference count causing the interface's memory to be freed when the count is 0 /// /// # Safety /// /// This function should only be called when the interface pointer is no longer used as calling `Release` /// on a non-aliased interface pointer and then using that interface pointer may result in use after free. /// /// This function takes `*mut Self` because the object may be freed by the time this method returns. /// Taking `&self` would violate Rust's rules on reference lifetime. unsafefn Release(self_: *mutSelf) -> u32;
/// Returns `true` if the reference count of the box is equal to 1. fn is_reference_count_one(&self) -> bool;
/// Gets the trust level of the current object. unsafefn GetTrustLevel(&self, value: *mut i32) -> HRESULT;
/// Given a reference to an inner type, returns a reference to the outer shared type. /// /// # Safety /// /// This function should only be called from methods that implement COM interfaces, i.e. /// implementations of methods on `IFoo_Impl` traits. // TODO: This can be made safe, if IFoo_Impl are moved to the Object_Impl types. // That requires some substantial redesign, though. unsafefn from_inner_ref(inner: &Self::Impl) -> &Self;
/// Gets a borrowed reference to an interface that is implemented by this ComObject. /// /// The returned reference does not have an additional reference count. /// You can AddRef it by calling to_owned(). #[inline(always)] fn as_interface<I: Interface>(&self) -> InterfaceRef<'_, I> where Self: ComObjectInterface<I>,
{
<Selfas ComObjectInterface<I>>::as_interface_ref(self)
}
/// Gets an owned (counted) reference to an interface that is implemented by this ComObject. #[inline(always)] fn to_interface<I: Interface>(&self) -> I where Self: ComObjectInterface<I>,
{
<Selfas ComObjectInterface<I>>::as_interface_ref(self).to_owned()
}
/// Creates a new owned reference to this object. /// /// # Safety /// /// This function can only be safely called by `<Foo>_Impl` objects that are embedded in a /// `ComObject`. Since we only allow safe Rust code to access these objects using a `ComObject` /// or a `&<Foo>_Impl` that points within a `ComObject`, this is safe. fn to_object(&self) -> ComObject<Self::Impl> where Self::Impl: ComObjectInner<Outer = Self>;
/// The distance from the start of `<Foo>_Impl` to the `this` field within it, measured in /// pointer-sized elements. The `this` field contains the `MyApp` instance. const INNER_OFFSET_IN_POINTERS: usize;
}
impl IUnknown_Vtbl { pubconstfn new<T: IUnknownImpl, const OFFSET: isize>() -> Self { unsafeextern"system"fn QueryInterface<T: IUnknownImpl, const OFFSET: isize>(
this: *mut c_void,
iid: *const GUID,
interface: *mut *mut c_void,
) -> HRESULT { let this = (this as *mut *mut c_void).offset(OFFSET) as *mut T;
(*this).QueryInterface(iid, interface)
} unsafeextern"system"fn AddRef<T: IUnknownImpl, const OFFSET: isize>(
this: *mut c_void,
) -> u32 { let this = (this as *mut *mut c_void).offset(OFFSET) as *mut T;
(*this).AddRef()
} unsafeextern"system"fn Release<T: IUnknownImpl, const OFFSET: isize>(
this: *mut c_void,
) -> u32 { let this = (this as *mut *mut c_void).offset(OFFSET) as *mut T;
T::Release(this)
} Self {
QueryInterface: QueryInterface::<T, OFFSET>,
AddRef: AddRef::<T, OFFSET>,
Release: Release::<T, OFFSET>,
}
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-18)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.