windows_result/
com.rs

1use super::*;
2
3#[doc(hidden)]
4#[macro_export]
5macro_rules! com_call {
6    ($vtbl:ty, $this:ident.$method:ident($($args:tt)*)) => {
7        ((&**($this.as_raw() as *mut *mut $vtbl)).$method)($this.as_raw(), $($args)*)
8    }
9}
10
11#[repr(transparent)]
12pub struct ComPtr(core::ptr::NonNull<core::ffi::c_void>);
13
14impl ComPtr {
15    pub fn as_raw(&self) -> *mut core::ffi::c_void {
16        unsafe { core::mem::transmute_copy(self) }
17    }
18
19    pub fn cast(&self, iid: &GUID) -> Option<Self> {
20        let mut result = None;
21        unsafe {
22            com_call!(
23                IUnknown_Vtbl,
24                self.QueryInterface(iid, &mut result as *mut _ as _)
25            );
26        }
27        result
28    }
29}
30
31impl PartialEq for ComPtr {
32    fn eq(&self, other: &Self) -> bool {
33        self.cast(&IID_IUnknown).unwrap().0 == other.cast(&IID_IUnknown).unwrap().0
34    }
35}
36
37impl Eq for ComPtr {}
38
39impl Clone for ComPtr {
40    fn clone(&self) -> Self {
41        unsafe {
42            com_call!(IUnknown_Vtbl, self.AddRef());
43        }
44        Self(self.0)
45    }
46}
47
48impl Drop for ComPtr {
49    fn drop(&mut self) {
50        unsafe {
51            com_call!(IUnknown_Vtbl, self.Release());
52        }
53    }
54}