From defd9edc24324a14a52c0c1fe6f6c3651c01d5c9 Mon Sep 17 00:00:00 2001 From: Kenny Kerr Date: Fri, 10 May 2024 13:23:54 -0500 Subject: [PATCH] ok --- crates/libs/core/src/ref.rs | 11 +++++ crates/tests/interface_core/tests/ref_ok.rs | 46 +++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 crates/tests/interface_core/tests/ref_ok.rs diff --git a/crates/libs/core/src/ref.rs b/crates/libs/core/src/ref.rs index c96a4c47cc..b1025fb985 100644 --- a/crates/libs/core/src/ref.rs +++ b/crates/libs/core/src/ref.rs @@ -4,6 +4,17 @@ use super::*; #[repr(transparent)] pub struct Ref<'a, T: Type>(T::Abi, std::marker::PhantomData<&'a T>); +impl<'a, T: Type, 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> std::ops::Deref for Ref<'a, T> { type Target = T::Default; fn deref(&self) -> &Self::Target { diff --git a/crates/tests/interface_core/tests/ref_ok.rs b/crates/tests/interface_core/tests/ref_ok.rs new file mode 100644 index 0000000000..7fbeb705f8 --- /dev/null +++ b/crates/tests/interface_core/tests/ref_ok.rs @@ -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, 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, 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(()) + } +}