Skip to content

Commit 04b7e92

Browse files
committed
Add ComPtr::new_class
1 parent 9bf0211 commit 04b7e92

File tree

2 files changed

+41
-3
lines changed

2 files changed

+41
-3
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ targets = [
2828
[dependencies]
2929
log = { version = "0.4", optional = true }
3030
winapi = { version = "0.3", features = [
31+
"combaseapi",
3132
"consoleapi",
3233
"errhandlingapi",
3334
"fileapi",

src/com.rs

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,17 @@ use std::fmt::{Debug, Error as FmtError, Formatter};
77
use std::mem::forget;
88
use std::ops::Deref;
99
use std::ptr::{null_mut, NonNull};
10-
use winapi::um::unknwnbase::IUnknown;
11-
use winapi::Interface;
10+
use winapi::{
11+
shared::{
12+
minwindef::DWORD,
13+
winerror::HRESULT,
14+
},
15+
um::{
16+
combaseapi,
17+
unknwnbase::IUnknown,
18+
}
19+
};
20+
use winapi::{Class, Interface};
1221

1322
// ComPtr to wrap COM interfaces sanely
1423
#[repr(transparent)]
@@ -57,6 +66,34 @@ impl<T> ComPtr<T> {
5766
}
5867
}
5968
}
69+
/// Instantiate the given class type.
70+
///
71+
/// This is a shorthand for [`CoCreateInstance`], using `C` and `T`'s `GUID`s for `rclsid` and
72+
/// `riid`, respectively. `cls_context` is passed into [`CoCreateInstance`]'s `dwClsContext`
73+
/// parameter, so see that documentation for details on what to pass for it.
74+
///
75+
/// Returns `Err(HRESULT)` if the call to [`CoCreateInstance`] failed.
76+
///
77+
/// [`CoCreateInstance`]: https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-cocreateinstance
78+
pub fn new_class<C: Class>(cls_context: DWORD) -> Result<ComPtr<T>, HRESULT>
79+
where T: Interface
80+
{
81+
unsafe {
82+
let mut raw_ptr: *mut T = null_mut();
83+
let hr = combaseapi::CoCreateInstance(
84+
&C::uuidof(),
85+
null_mut(),
86+
cls_context,
87+
&T::uuidof(),
88+
&mut raw_ptr as *mut _ as *mut _,
89+
);
90+
if hr == 0 {
91+
Ok(ComPtr::from_raw(raw_ptr))
92+
} else {
93+
Err(hr)
94+
}
95+
}
96+
}
6097
/// Casts up the inheritance chain
6198
pub fn up<U>(self) -> ComPtr<U>
6299
where
@@ -77,7 +114,7 @@ impl<T> ComPtr<T> {
77114
unsafe { &*(self.as_raw() as *mut IUnknown) }
78115
}
79116
/// Performs QueryInterface fun.
80-
pub fn cast<U>(&self) -> Result<ComPtr<U>, i32>
117+
pub fn cast<U>(&self) -> Result<ComPtr<U>, HRESULT>
81118
where
82119
U: Interface,
83120
{

0 commit comments

Comments
 (0)