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 |
7 | pub 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)] |
70 | pub unsafe fn from_raw_borrowed<T: Interface>(raw: &*mut std::ffi::c_void) -> Option<&T> { |
71 | T::from_raw_borrowed(raw) |
72 | } |
73 | |