1/// Provides low-level access to an interface vtable.
2///
3/// This trait is automatically implemented by the generated bindings and should not be
4/// implemented manually.
5///
6/// # Safety
7pub unsafe trait Interface: Sized {
8 type Vtable;
9
10 /// A reference to the interface's vtable
11 #[doc(hidden)]
12 fn vtable(&self) -> &Self::Vtable {
13 // SAFETY: the implementor of the trait guarantees that `Self` is castable to its vtable
14 unsafe { self.assume_vtable::<Self>() }
15 }
16
17 /// Cast this interface as a reference to the supplied interfaces `Vtable`
18 ///
19 /// # Safety
20 ///
21 /// This is safe if `T` is an equivalent interface to `Self` or a super interface.
22 /// In other words, `T::Vtable` must be equivalent to the beginning of `Self::Vtable`.
23 #[doc(hidden)]
24 unsafe fn assume_vtable<T: Interface>(&self) -> &T::Vtable {
25 &**(self.as_raw() as *mut *mut T::Vtable)
26 }
27
28 /// Returns the raw COM interface pointer. The resulting pointer continues to be owned by the `Interface` implementation.
29 #[inline(always)]
30 fn as_raw(&self) -> *mut std::ffi::c_void {
31 // SAFETY: implementors of this trait must guarantee that the implementing type has a pointer in-memory representation
32 unsafe { std::mem::transmute_copy(self) }
33 }
34
35 /// Returns the raw COM interface pointer and releases ownership. It the caller's responsibility to release the COM interface pointer.
36 fn into_raw(self) -> *mut std::ffi::c_void {
37 // SAFETY: implementors of this trait must guarantee that the implementing type has a pointer in-memory representation
38 let raw = self.as_raw();
39 std::mem::forget(self);
40 raw
41 }
42
43 /// Creates an `Interface` by taking ownership of the `raw` COM interface pointer.
44 ///
45 /// # Safety
46 ///
47 /// The `raw` pointer must be owned by the caller and represent a valid COM interface pointer. In other words,
48 /// it must point to a vtable beginning with the `IUnknown` function pointers and match the vtable of `Interface`.
49 unsafe fn from_raw(raw: *mut std::ffi::c_void) -> Self {
50 std::mem::transmute_copy(&raw)
51 }
52
53 /// Creates an `Interface` that is valid so long as the `raw` COM interface pointer is valid.
54 ///
55 /// # Safety
56 ///
57 /// The `raw` pointer must be a valid COM interface pointer. In other words, it must point to a vtable
58 /// beginning with the `IUnknown` function pointers and match the vtable of `Interface`.
59 unsafe fn from_raw_borrowed(raw: &*mut std::ffi::c_void) -> Option<&Self> {
60 if raw.is_null() {
61 None
62 } else {
63 Some(std::mem::transmute_copy(&raw))
64 }
65 }
66}
67
68/// # Safety
69#[doc(hidden)]
70pub unsafe fn from_raw_borrowed<T: Interface>(raw: &*mut std::ffi::c_void) -> Option<&T> {
71 T::from_raw_borrowed(raw)
72}
73