ferroui_microcom/
unknown.rs1use std::ffi::c_void;
2
3use crate::{Guid, RawHResult};
4
5pub unsafe trait Interface: Sized + 'static {
12 const IID: Guid;
14 const NAME: &'static str;
16 type Vtbl: 'static;
17
18 fn matches_iid(iid: &Guid) -> bool;
22
23 #[inline]
24 fn as_unknown(&self) -> &IUnknown {
25 unsafe { &*(self as *const Self as *const IUnknown) }
27 }
28
29 #[inline]
30 fn as_raw(&self) -> *mut Self {
31 self as *const Self as *mut Self
32 }
33}
34
35#[repr(C)]
36pub struct IUnknownVtbl {
37 pub query_interface: unsafe extern "system" fn(
38 this: *mut c_void,
39 riid: *const Guid,
40 ppv: *mut *mut c_void,
41 ) -> RawHResult,
42 pub add_ref: unsafe extern "system" fn(this: *mut c_void) -> u32,
43 pub release: unsafe extern "system" fn(this: *mut c_void) -> u32,
44}
45
46#[repr(C)]
48pub struct IUnknown {
49 vtbl: *const IUnknownVtbl,
50}
51
52unsafe impl Interface for IUnknown {
53 const IID: Guid = Guid::from_u128(0x00000000_0000_0000_C000_000000000046);
54 const NAME: &'static str = "IUnknown";
55 type Vtbl = IUnknownVtbl;
56
57 fn matches_iid(iid: &Guid) -> bool {
58 *iid == Self::IID || *iid == Self::IID.as_com_h_materialized()
59 }
60}
61
62impl IUnknown {
63 #[inline]
66 pub unsafe fn query_interface_raw(&self, riid: &Guid, ppv: *mut *mut c_void) -> RawHResult {
67 ((*self.vtbl).query_interface)(self as *const _ as *mut c_void, riid, ppv)
68 }
69
70 #[inline]
73 pub unsafe fn add_ref(&self) -> u32 {
74 ((*self.vtbl).add_ref)(self as *const _ as *mut c_void)
75 }
76
77 #[inline]
80 pub unsafe fn release(&self) -> u32 {
81 ((*self.vtbl).release)(self as *const _ as *mut c_void)
82 }
83}
84
85pub trait IUnknownImpl {}
90impl<T: ?Sized> IUnknownImpl for T {}