Skip to content

Commit

Permalink
test
Browse files Browse the repository at this point in the history
  • Loading branch information
kennykerr committed Jan 15, 2025
1 parent 76b0602 commit dfeb02b
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 0 deletions.
6 changes: 6 additions & 0 deletions crates/libs/core/src/out_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,9 @@ impl<T: Type<T>> OutRef<'_, T> {
}
}
}

impl<'a, T: Type<T>> From<&'a mut T::Default> for OutRef<'a, T> {
fn from(from: &'a mut T::Default) -> Self {
unsafe { core::mem::transmute(from) }
}
}
92 changes: 92 additions & 0 deletions crates/tests/bindgen/src/delegate_cpp_ref.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#![allow(
non_snake_case,
non_upper_case_globals,
non_camel_case_types,
dead_code,
clippy::all
)]

pub const CLASS_E_CLASSNOTAVAILABLE: windows_core::HRESULT =
windows_core::HRESULT(0x80040111_u32 as _);
#[repr(transparent)]
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct D3D_FEATURE_LEVEL(pub i32);
windows_core::imp::define_interface!(
IActivationFactory,
IActivationFactory_Vtbl,
0x00000035_0000_0000_c000_000000000046
);
windows_core::imp::interface_hierarchy!(
IActivationFactory,
windows_core::IUnknown,
windows_core::IInspectable
);
impl IActivationFactory {
pub unsafe fn ActivateInstance(&self) -> windows_core::Result<windows_core::IInspectable> {
unsafe {
let mut result__ = core::mem::zeroed();
(windows_core::Interface::vtable(self).ActivateInstance)(
windows_core::Interface::as_raw(self),
&mut result__,
)
.and_then(|| windows_core::Type::from_abi(result__))
}
}
}
#[repr(C)]
pub struct IActivationFactory_Vtbl {
pub base__: windows_core::IInspectable_Vtbl,
pub ActivateInstance: unsafe extern "system" fn(
*mut core::ffi::c_void,
*mut *mut core::ffi::c_void,
) -> windows_core::HRESULT,
}
pub trait IActivationFactory_Impl: windows_core::IUnknownImpl {
fn ActivateInstance(&self) -> windows_core::Result<windows_core::IInspectable>;
}
impl IActivationFactory_Vtbl {
pub const fn new<Identity: IActivationFactory_Impl, const OFFSET: isize>() -> Self {
unsafe extern "system" fn ActivateInstance<
Identity: IActivationFactory_Impl,
const OFFSET: isize,
>(
this: *mut core::ffi::c_void,
instance: *mut *mut core::ffi::c_void,
) -> windows_core::HRESULT {
unsafe {
let this: &Identity =
&*((this as *const *const ()).offset(OFFSET) as *const Identity);
match IActivationFactory_Impl::ActivateInstance(this) {
Ok(ok__) => {
instance.write(core::mem::transmute(ok__));
windows_core::HRESULT(0)
}
Err(err) => err.into(),
}
}
}
Self {
base__: windows_core::IInspectable_Vtbl::new::<Identity, IActivationFactory, OFFSET>(),
ActivateInstance: ActivateInstance::<Identity, OFFSET>,
}
}
pub fn matches(iid: &windows_core::GUID) -> bool {
iid == &<IActivationFactory as windows_core::Interface>::IID
}
}
impl windows_core::RuntimeName for IActivationFactory {}
pub type PFNGETACTIVATIONFACTORY = Option<
unsafe extern "system" fn(
param0: windows_core::Ref<windows_core::HSTRING>,
param1: windows_core::OutRef<'_, IActivationFactory>,
) -> windows_core::HRESULT,
>;
pub type PFN_D3D12_CREATE_DEVICE = Option<
unsafe extern "system" fn(
param0: windows_core::Ref<windows_core::IUnknown>,
param1: D3D_FEATURE_LEVEL,
param2: *const windows_core::GUID,
param3: *mut *mut core::ffi::c_void,
) -> windows_core::HRESULT,
>;
pub const S_OK: windows_core::HRESULT = windows_core::HRESULT(0x0_u32 as _);
1 change: 1 addition & 0 deletions crates/tests/bindgen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub mod default_assumed;
pub mod default_default;
pub mod delegate;
pub mod delegate_cpp;
pub mod delegate_cpp_ref;
pub mod delegate_generic;
pub mod deps;
pub mod derive_cpp_enum;
Expand Down
61 changes: 61 additions & 0 deletions crates/tests/bindgen/tests/delegate_cpp_ref.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use test_bindgen::delegate_cpp_ref::*;
use windows_core::*;

#[test]
fn test_factory() {
static FACTORY: StaticComObject<Factory> = Factory.into_static();

#[implement(IActivationFactory)]
struct Factory;

impl IActivationFactory_Impl for Factory_Impl {
fn ActivateInstance(&self) -> Result<IInspectable> {
todo!()
}
}

unsafe extern "system" fn callback(
name: Ref<windows_core::HSTRING>,
factory: OutRef<IActivationFactory>,
) -> HRESULT {
if *name == "Factory" {
factory.write(Some(FACTORY.to_interface())).into()
} else {
_ = factory.write(None);
CLASS_E_CLASSNOTAVAILABLE
}
}

// This is a roundabout way to test that PFNGETACTIVATIONFACTORY can be both implemented and called in Rust.
let _callback: PFNGETACTIVATIONFACTORY = Some(callback);

unsafe {
let mut factory: Option<IActivationFactory> = None;

assert_eq!(
CLASS_E_CLASSNOTAVAILABLE,
callback(
// transmute_copy is required here since Ref doesn't have a lifetime parameter and thus is unsafe
// to implement From or construct a Ref without unsafe code.
std::mem::transmute_copy(h!("invalid")),
// OutRef provides a safe From implementation since it includes a lifetime parameter.
OutRef::from(&mut factory)
)
);

assert!(factory.is_none());

assert_eq!(
S_OK,
callback(
std::mem::transmute_copy(h!("Factory")),
OutRef::from(&mut factory)
)
);

assert_eq!(
FACTORY.to_interface::<IActivationFactory>(),
factory.unwrap()
);
}
}
1 change: 1 addition & 0 deletions crates/tools/bindgen/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ fn main() {
test("--out delegate.rs --filter DeferralCompletedHandler");
test("--out delegate_generic.rs --filter EventHandler");
test("--out delegate_cpp.rs --filter GetProcAddress EnumWindows");
test("--out delegate_cpp_ref.rs --filter PFN_D3D12_CREATE_DEVICE PFNGETACTIVATIONFACTORY S_OK CLASS_E_CLASSNOTAVAILABLE");

// Tests for classes
test("--out class.rs --filter Deferral");
Expand Down

0 comments on commit dfeb02b

Please sign in to comment.