Skip to content

Commit

Permalink
Simplify derefencing Ref interface parameters (#3027)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennykerr authored May 10, 2024
1 parent 5559099 commit 3da42d8
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
11 changes: 11 additions & 0 deletions crates/libs/core/src/ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@ use super::*;
#[repr(transparent)]
pub struct Ref<'a, T: Type<T>>(T::Abi, std::marker::PhantomData<&'a T>);

impl<'a, T: Type<T, Default = Option<T>, Abi = *mut std::ffi::c_void>> Ref<'a, T> {
/// Converts the argument to a [Result<&T>] reference.
pub fn ok(&self) -> Result<&T> {
if self.0.is_null() {
Err(Error::from_hresult(imp::E_POINTER))
} else {
unsafe { Ok(std::mem::transmute::<&*mut std::ffi::c_void, &T>(&self.0)) }
}
}
}

impl<'a, T: Type<T>> std::ops::Deref for Ref<'a, T> {
type Target = T::Default;
fn deref(&self) -> &Self::Target {
Expand Down
46 changes: 46 additions & 0 deletions crates/tests/interface_core/tests/ref_ok.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#![allow(non_snake_case)]

use windows_core::*;

#[interface("09428a59-5b40-4e4c-9175-e7a78514316d")]
unsafe trait ITest: IUnknown {
unsafe fn Test(&self, result: &mut i32) -> Result<()>;
unsafe fn TestOther(&self, other: Ref<ITest>, result: &mut i32) -> Result<()>;
}

#[implement(ITest)]
struct Test(i32);

impl ITest_Impl for Test {
unsafe fn Test(&self, result: &mut i32) -> Result<()> {
*result = self.0;
Ok(())
}
unsafe fn TestOther(&self, other: Ref<ITest>, result: &mut i32) -> Result<()> {
other.ok()?.Test(result)
}
}

#[test]
fn test() -> Result<()> {
unsafe {
let a: ITest = Test(123).into();
let b: ITest = Test(456).into();

let mut result = 0;

a.Test(&mut result)?;
assert_eq!(result, 123);

b.Test(&mut result)?;
assert_eq!(result, 456);

b.TestOther(&a, &mut result)?;
assert_eq!(result, 123);

a.TestOther(&b, &mut result)?;
assert_eq!(result, 456);

Ok(())
}
}

0 comments on commit 3da42d8

Please sign in to comment.