diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index fe45a03445..0250a68cbf 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -227,6 +227,10 @@ jobs: run: cargo clippy -p test_query_signature - name: Clippy test_readme run: cargo clippy -p test_readme + - name: Clippy test_reference + run: cargo clippy -p test_reference + - name: Clippy test_reference_client + run: cargo clippy -p test_reference_client - name: Clippy test_reference_float run: cargo clippy -p test_reference_float - name: Clippy test_registry diff --git a/.github/workflows/raw-dylib.yml b/.github/workflows/raw-dylib.yml index d8981511cd..e8840e81ee 100644 --- a/.github/workflows/raw-dylib.yml +++ b/.github/workflows/raw-dylib.yml @@ -256,14 +256,18 @@ jobs: run: cargo test -p test_query_signature --target ${{ matrix.target }} ${{ matrix.etc }} - name: Test test_readme run: cargo test -p test_readme --target ${{ matrix.target }} ${{ matrix.etc }} + - name: Test test_reference + run: cargo test -p test_reference --target ${{ matrix.target }} ${{ matrix.etc }} + - name: Test test_reference_client + run: cargo test -p test_reference_client --target ${{ matrix.target }} ${{ matrix.etc }} - name: Test test_reference_float run: cargo test -p test_reference_float --target ${{ matrix.target }} ${{ matrix.etc }} + - name: Clean + run: cargo clean - name: Test test_registry run: cargo test -p test_registry --target ${{ matrix.target }} ${{ matrix.etc }} - name: Test test_registry_default run: cargo test -p test_registry_default --target ${{ matrix.target }} ${{ matrix.etc }} - - name: Clean - run: cargo clean - name: Test test_reserved run: cargo test -p test_reserved --target ${{ matrix.target }} ${{ matrix.etc }} - name: Test test_resources diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7521ca60b2..7396dea90d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -253,14 +253,18 @@ jobs: run: cargo test -p test_query_signature --target ${{ matrix.target }} ${{ matrix.etc }} - name: Test test_readme run: cargo test -p test_readme --target ${{ matrix.target }} ${{ matrix.etc }} + - name: Test test_reference + run: cargo test -p test_reference --target ${{ matrix.target }} ${{ matrix.etc }} + - name: Test test_reference_client + run: cargo test -p test_reference_client --target ${{ matrix.target }} ${{ matrix.etc }} - name: Test test_reference_float run: cargo test -p test_reference_float --target ${{ matrix.target }} ${{ matrix.etc }} + - name: Clean + run: cargo clean - name: Test test_registry run: cargo test -p test_registry --target ${{ matrix.target }} ${{ matrix.etc }} - name: Test test_registry_default run: cargo test -p test_registry_default --target ${{ matrix.target }} ${{ matrix.etc }} - - name: Clean - run: cargo clean - name: Test test_reserved run: cargo test -p test_reserved --target ${{ matrix.target }} ${{ matrix.etc }} - name: Test test_resources diff --git a/crates/libs/bindgen/src/lib.rs b/crates/libs/bindgen/src/lib.rs index 0773ec4ebf..c785043bb1 100644 --- a/crates/libs/bindgen/src/lib.rs +++ b/crates/libs/bindgen/src/lib.rs @@ -161,8 +161,8 @@ where let reader = Reader::new(expand_input(&input)); let filter = Filter::new(reader, &include, &exclude); - let types = TypeMap::filter(reader, &filter); let references = References::new(reader, references); + let types = TypeMap::filter(reader, &filter, &references); let derive = Derive::new(reader, &types, &derive); let config = Box::leak(Box::new(Config { diff --git a/crates/libs/bindgen/src/references.rs b/crates/libs/bindgen/src/references.rs index 1e447f355e..7454a2dc97 100644 --- a/crates/libs/bindgen/src/references.rs +++ b/crates/libs/bindgen/src/references.rs @@ -64,7 +64,7 @@ pub struct Reference { pub style: ReferenceStyle, // how to generate the type path } -#[derive(Debug)] +#[derive(Debug, Default)] pub struct References(Vec); impl References { @@ -74,7 +74,7 @@ impl References { .into_iter() .map(|stage| { let filter = Filter::new(reader, &[&stage.path], &[]); - let types = TypeMap::filter(reader, &filter); + let types = TypeMap::filter(reader, &filter, &References::default()); Reference { name: stage.name, diff --git a/crates/libs/bindgen/src/type_map.rs b/crates/libs/bindgen/src/type_map.rs index 7201e2fbba..e1cb9f359e 100644 --- a/crates/libs/bindgen/src/type_map.rs +++ b/crates/libs/bindgen/src/type_map.rs @@ -16,7 +16,7 @@ impl TypeMap { Self(HashMap::new()) } - pub fn filter(reader: &'static Reader, filter: &Filter) -> Self { + pub fn filter(reader: &'static Reader, filter: &Filter, references: &References) -> Self { let mut dependencies = Self::new(); for namespace in reader.keys() { @@ -33,7 +33,7 @@ impl TypeMap { continue; } - dependencies.combine(&item_dependencies); + dependencies.combine_references(&item_dependencies, references); } } } @@ -46,6 +46,17 @@ impl TypeMap { self.0.entry(ty.type_name()).or_default().insert(ty) } + fn combine_references(&mut self, other: &Self, references: &References) { + for (tn, types) in &other.0 { + if references.contains(*tn).is_none() { + let set = self.0.entry(*tn).or_default(); + types.iter().for_each(|ty| { + set.insert(ty.clone()); + }); + } + } + } + pub fn combine(&mut self, other: &Self) { for (name, types) in &other.0 { let set = self.0.entry(*name).or_default(); diff --git a/crates/tests/bindgen/src/lib.rs b/crates/tests/bindgen/src/lib.rs index 038c0143e9..109047fa3d 100644 --- a/crates/tests/bindgen/src/lib.rs +++ b/crates/tests/bindgen/src/lib.rs @@ -59,13 +59,17 @@ pub mod interface_sys; pub mod interface_sys_no_core; pub mod multi; pub mod multi_sys; +pub mod reference_async_action; +pub mod reference_async_action_reference; +pub mod reference_async_info_no_status; +pub mod reference_async_info_status_filter; +pub mod reference_async_info_status_reference; pub mod reference_dependency_flat; pub mod reference_dependency_full; pub mod reference_dependency_skip_root; pub mod reference_dependent_flat; pub mod reference_dependent_full; pub mod reference_dependent_skip_root; -pub mod reference_windows; pub mod sort; pub mod struct_cpp_sys; pub mod struct_cpp_win; diff --git a/crates/tests/bindgen/src/reference_async_action.rs b/crates/tests/bindgen/src/reference_async_action.rs new file mode 100644 index 0000000000..b67dd8f619 --- /dev/null +++ b/crates/tests/bindgen/src/reference_async_action.rs @@ -0,0 +1,230 @@ +#![allow( + non_snake_case, + non_upper_case_globals, + non_camel_case_types, + dead_code, + clippy::all +)] + +windows_core::imp::define_interface!( + IAsyncAction, + IAsyncAction_Vtbl, + 0x5a648006_843a_4da9_865b_9d26e5dfad7b +); +impl windows_core::RuntimeType for IAsyncAction { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!( + IAsyncAction, + windows_core::IUnknown, + windows_core::IInspectable +); +windows_core::imp::required_hierarchy!(IAsyncAction, IAsyncInfo); +impl IAsyncAction { + pub fn GetResults(&self) -> windows_core::Result<()> { + let this = self; + unsafe { + (windows_core::Interface::vtable(this).GetResults)(windows_core::Interface::as_raw( + this, + )) + .ok() + } + } + pub fn Id(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Id)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn ErrorCode(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ErrorCode)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn Cancel(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + (windows_core::Interface::vtable(this).Cancel)(windows_core::Interface::as_raw(this)) + .ok() + } + } + pub fn Close(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)) + .ok() + } + } +} +unsafe impl Send for IAsyncAction {} +unsafe impl Sync for IAsyncAction {} +impl windows_core::RuntimeName for IAsyncAction { + const NAME: &'static str = "Windows.Foundation.IAsyncAction"; +} +pub trait IAsyncAction_Impl: IAsyncInfo_Impl { + fn GetResults(&self) -> windows_core::Result<()>; +} +impl IAsyncAction_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetResults( + this: *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAsyncAction_Impl::GetResults(this).into() + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + put_Completed: 0, + get_Completed: 0, + GetResults: GetResults::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +pub struct IAsyncAction_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + put_Completed: usize, + get_Completed: usize, + pub GetResults: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!( + IAsyncInfo, + IAsyncInfo_Vtbl, + 0x00000036_0000_0000_c000_000000000046 +); +impl windows_core::RuntimeType for IAsyncInfo { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!( + IAsyncInfo, + windows_core::IUnknown, + windows_core::IInspectable +); +impl IAsyncInfo { + pub fn Id(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Id)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn ErrorCode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ErrorCode)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn Cancel(&self) -> windows_core::Result<()> { + let this = self; + unsafe { + (windows_core::Interface::vtable(this).Cancel)(windows_core::Interface::as_raw(this)) + .ok() + } + } + pub fn Close(&self) -> windows_core::Result<()> { + let this = self; + unsafe { + (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)) + .ok() + } + } +} +impl windows_core::RuntimeName for IAsyncInfo { + const NAME: &'static str = "Windows.Foundation.IAsyncInfo"; +} +pub trait IAsyncInfo_Impl: windows_core::IUnknownImpl { + fn Id(&self) -> windows_core::Result; + fn ErrorCode(&self) -> windows_core::Result; + fn Cancel(&self) -> windows_core::Result<()>; + fn Close(&self) -> windows_core::Result<()>; +} +impl IAsyncInfo_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Id( + this: *mut core::ffi::c_void, + result__: *mut u32, + ) -> windows_core::HRESULT { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAsyncInfo_Impl::Id(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + unsafe extern "system" fn ErrorCode( + this: *mut core::ffi::c_void, + result__: *mut windows_core::HRESULT, + ) -> windows_core::HRESULT { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAsyncInfo_Impl::ErrorCode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + unsafe extern "system" fn Cancel( + this: *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAsyncInfo_Impl::Cancel(this).into() + } + unsafe extern "system" fn Close( + this: *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAsyncInfo_Impl::Close(this).into() + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Id: Id::, + get_Status: 0, + ErrorCode: ErrorCode::, + Cancel: Cancel::, + Close: Close::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +pub struct IAsyncInfo_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Id: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + get_Status: usize, + pub ErrorCode: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut windows_core::HRESULT, + ) -> windows_core::HRESULT, + pub Cancel: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, + pub Close: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, +} diff --git a/crates/tests/bindgen/src/reference_async_action_reference.rs b/crates/tests/bindgen/src/reference_async_action_reference.rs new file mode 100644 index 0000000000..88d7b3fb12 --- /dev/null +++ b/crates/tests/bindgen/src/reference_async_action_reference.rs @@ -0,0 +1,104 @@ +#![allow( + non_snake_case, + non_upper_case_globals, + non_camel_case_types, + dead_code, + clippy::all +)] + +windows_core::imp::define_interface!( + IAsyncAction, + IAsyncAction_Vtbl, + 0x5a648006_843a_4da9_865b_9d26e5dfad7b +); +impl windows_core::RuntimeType for IAsyncAction { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!( + IAsyncAction, + windows_core::IUnknown, + windows_core::IInspectable +); +windows_core::imp::required_hierarchy!(IAsyncAction, windows::Foundation::IAsyncInfo); +impl IAsyncAction { + pub fn GetResults(&self) -> windows_core::Result<()> { + let this = self; + unsafe { + (windows_core::Interface::vtable(this).GetResults)(windows_core::Interface::as_raw( + this, + )) + .ok() + } + } + pub fn Id(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Id)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn ErrorCode(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ErrorCode)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn Cancel(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + (windows_core::Interface::vtable(this).Cancel)(windows_core::Interface::as_raw(this)) + .ok() + } + } + pub fn Close(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)) + .ok() + } + } +} +unsafe impl Send for IAsyncAction {} +unsafe impl Sync for IAsyncAction {} +impl windows_core::RuntimeName for IAsyncAction { + const NAME: &'static str = "Windows.Foundation.IAsyncAction"; +} +pub trait IAsyncAction_Impl: windows::Foundation::IAsyncInfo_Impl { + fn GetResults(&self) -> windows_core::Result<()>; +} +impl IAsyncAction_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetResults( + this: *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAsyncAction_Impl::GetResults(this).into() + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + put_Completed: 0, + get_Completed: 0, + GetResults: GetResults::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +pub struct IAsyncAction_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + put_Completed: usize, + get_Completed: usize, + pub GetResults: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, +} diff --git a/crates/tests/bindgen/src/reference_async_info_no_status.rs b/crates/tests/bindgen/src/reference_async_info_no_status.rs new file mode 100644 index 0000000000..b8603453e0 --- /dev/null +++ b/crates/tests/bindgen/src/reference_async_info_no_status.rs @@ -0,0 +1,134 @@ +#![allow( + non_snake_case, + non_upper_case_globals, + non_camel_case_types, + dead_code, + clippy::all +)] + +windows_core::imp::define_interface!( + IAsyncInfo, + IAsyncInfo_Vtbl, + 0x00000036_0000_0000_c000_000000000046 +); +impl windows_core::RuntimeType for IAsyncInfo { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!( + IAsyncInfo, + windows_core::IUnknown, + windows_core::IInspectable +); +impl IAsyncInfo { + pub fn Id(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Id)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn ErrorCode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ErrorCode)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn Cancel(&self) -> windows_core::Result<()> { + let this = self; + unsafe { + (windows_core::Interface::vtable(this).Cancel)(windows_core::Interface::as_raw(this)) + .ok() + } + } + pub fn Close(&self) -> windows_core::Result<()> { + let this = self; + unsafe { + (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)) + .ok() + } + } +} +impl windows_core::RuntimeName for IAsyncInfo { + const NAME: &'static str = "Windows.Foundation.IAsyncInfo"; +} +pub trait IAsyncInfo_Impl: windows_core::IUnknownImpl { + fn Id(&self) -> windows_core::Result; + fn ErrorCode(&self) -> windows_core::Result; + fn Cancel(&self) -> windows_core::Result<()>; + fn Close(&self) -> windows_core::Result<()>; +} +impl IAsyncInfo_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Id( + this: *mut core::ffi::c_void, + result__: *mut u32, + ) -> windows_core::HRESULT { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAsyncInfo_Impl::Id(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + unsafe extern "system" fn ErrorCode( + this: *mut core::ffi::c_void, + result__: *mut windows_core::HRESULT, + ) -> windows_core::HRESULT { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAsyncInfo_Impl::ErrorCode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + unsafe extern "system" fn Cancel( + this: *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAsyncInfo_Impl::Cancel(this).into() + } + unsafe extern "system" fn Close( + this: *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAsyncInfo_Impl::Close(this).into() + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Id: Id::, + get_Status: 0, + ErrorCode: ErrorCode::, + Cancel: Cancel::, + Close: Close::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +pub struct IAsyncInfo_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Id: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + get_Status: usize, + pub ErrorCode: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut windows_core::HRESULT, + ) -> windows_core::HRESULT, + pub Cancel: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, + pub Close: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, +} diff --git a/crates/tests/bindgen/src/reference_async_info_status_filter.rs b/crates/tests/bindgen/src/reference_async_info_status_filter.rs new file mode 100644 index 0000000000..068ffc7136 --- /dev/null +++ b/crates/tests/bindgen/src/reference_async_info_status_filter.rs @@ -0,0 +1,178 @@ +#![allow( + non_snake_case, + non_upper_case_globals, + non_camel_case_types, + dead_code, + clippy::all +)] + +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct AsyncStatus(pub i32); +impl AsyncStatus { + pub const Canceled: Self = Self(2i32); + pub const Completed: Self = Self(1i32); + pub const Error: Self = Self(3i32); + pub const Started: Self = Self(0i32); +} +impl windows_core::TypeKind for AsyncStatus { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for AsyncStatus { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Foundation.AsyncStatus;i4)"); +} +windows_core::imp::define_interface!( + IAsyncInfo, + IAsyncInfo_Vtbl, + 0x00000036_0000_0000_c000_000000000046 +); +impl windows_core::RuntimeType for IAsyncInfo { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!( + IAsyncInfo, + windows_core::IUnknown, + windows_core::IInspectable +); +impl IAsyncInfo { + pub fn Id(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Id)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn Status(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Status)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn ErrorCode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ErrorCode)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn Cancel(&self) -> windows_core::Result<()> { + let this = self; + unsafe { + (windows_core::Interface::vtable(this).Cancel)(windows_core::Interface::as_raw(this)) + .ok() + } + } + pub fn Close(&self) -> windows_core::Result<()> { + let this = self; + unsafe { + (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)) + .ok() + } + } +} +impl windows_core::RuntimeName for IAsyncInfo { + const NAME: &'static str = "Windows.Foundation.IAsyncInfo"; +} +pub trait IAsyncInfo_Impl: windows_core::IUnknownImpl { + fn Id(&self) -> windows_core::Result; + fn Status(&self) -> windows_core::Result; + fn ErrorCode(&self) -> windows_core::Result; + fn Cancel(&self) -> windows_core::Result<()>; + fn Close(&self) -> windows_core::Result<()>; +} +impl IAsyncInfo_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Id( + this: *mut core::ffi::c_void, + result__: *mut u32, + ) -> windows_core::HRESULT { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAsyncInfo_Impl::Id(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + unsafe extern "system" fn Status( + this: *mut core::ffi::c_void, + result__: *mut AsyncStatus, + ) -> windows_core::HRESULT { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAsyncInfo_Impl::Status(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + unsafe extern "system" fn ErrorCode( + this: *mut core::ffi::c_void, + result__: *mut windows_core::HRESULT, + ) -> windows_core::HRESULT { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAsyncInfo_Impl::ErrorCode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + unsafe extern "system" fn Cancel( + this: *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAsyncInfo_Impl::Cancel(this).into() + } + unsafe extern "system" fn Close( + this: *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAsyncInfo_Impl::Close(this).into() + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Id: Id::, + Status: Status::, + ErrorCode: ErrorCode::, + Cancel: Cancel::, + Close: Close::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +pub struct IAsyncInfo_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Id: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub Status: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut AsyncStatus, + ) -> windows_core::HRESULT, + pub ErrorCode: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut windows_core::HRESULT, + ) -> windows_core::HRESULT, + pub Cancel: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, + pub Close: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, +} diff --git a/crates/tests/bindgen/src/reference_async_info_status_reference.rs b/crates/tests/bindgen/src/reference_async_info_status_reference.rs new file mode 100644 index 0000000000..f84bc8103d --- /dev/null +++ b/crates/tests/bindgen/src/reference_async_info_status_reference.rs @@ -0,0 +1,162 @@ +#![allow( + non_snake_case, + non_upper_case_globals, + non_camel_case_types, + dead_code, + clippy::all +)] + +windows_core::imp::define_interface!( + IAsyncInfo, + IAsyncInfo_Vtbl, + 0x00000036_0000_0000_c000_000000000046 +); +impl windows_core::RuntimeType for IAsyncInfo { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!( + IAsyncInfo, + windows_core::IUnknown, + windows_core::IInspectable +); +impl IAsyncInfo { + pub fn Id(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Id)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn Status(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Status)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn ErrorCode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ErrorCode)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| result__) + } + } + pub fn Cancel(&self) -> windows_core::Result<()> { + let this = self; + unsafe { + (windows_core::Interface::vtable(this).Cancel)(windows_core::Interface::as_raw(this)) + .ok() + } + } + pub fn Close(&self) -> windows_core::Result<()> { + let this = self; + unsafe { + (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)) + .ok() + } + } +} +impl windows_core::RuntimeName for IAsyncInfo { + const NAME: &'static str = "Windows.Foundation.IAsyncInfo"; +} +pub trait IAsyncInfo_Impl: windows_core::IUnknownImpl { + fn Id(&self) -> windows_core::Result; + fn Status(&self) -> windows_core::Result; + fn ErrorCode(&self) -> windows_core::Result; + fn Cancel(&self) -> windows_core::Result<()>; + fn Close(&self) -> windows_core::Result<()>; +} +impl IAsyncInfo_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Id( + this: *mut core::ffi::c_void, + result__: *mut u32, + ) -> windows_core::HRESULT { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAsyncInfo_Impl::Id(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + unsafe extern "system" fn Status( + this: *mut core::ffi::c_void, + result__: *mut windows::Foundation::AsyncStatus, + ) -> windows_core::HRESULT { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAsyncInfo_Impl::Status(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + unsafe extern "system" fn ErrorCode( + this: *mut core::ffi::c_void, + result__: *mut windows_core::HRESULT, + ) -> windows_core::HRESULT { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAsyncInfo_Impl::ErrorCode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + unsafe extern "system" fn Cancel( + this: *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAsyncInfo_Impl::Cancel(this).into() + } + unsafe extern "system" fn Close( + this: *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAsyncInfo_Impl::Close(this).into() + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Id: Id::, + Status: Status::, + ErrorCode: ErrorCode::, + Cancel: Cancel::, + Close: Close::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +pub struct IAsyncInfo_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Id: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub Status: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut windows::Foundation::AsyncStatus, + ) -> windows_core::HRESULT, + pub ErrorCode: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut windows_core::HRESULT, + ) -> windows_core::HRESULT, + pub Cancel: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, + pub Close: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, +} diff --git a/crates/tests/bindgen/src/reference_dependent_flat.rs b/crates/tests/bindgen/src/reference_dependent_flat.rs index 2c5f9468dd..965cc6a435 100644 --- a/crates/tests/bindgen/src/reference_dependent_flat.rs +++ b/crates/tests/bindgen/src/reference_dependent_flat.rs @@ -8,60 +8,6 @@ pub mod Windows { pub mod Foundation { - windows_core::imp::define_interface!( - IClosable, - IClosable_Vtbl, - 0x30d5a829_7fa4_4026_83bb_d75bae4ea99e - ); - impl windows_core::RuntimeType for IClosable { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_interface::(); - } - windows_core::imp::interface_hierarchy!( - IClosable, - windows_core::IUnknown, - windows_core::IInspectable - ); - impl IClosable { - pub fn Close(&self) -> windows_core::Result<()> { - let this = self; - unsafe { - (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw( - this, - )) - .ok() - } - } - } - impl windows_core::RuntimeName for IClosable { - const NAME: &'static str = "Windows.Foundation.IClosable"; - } - pub trait IClosable_Impl: windows_core::IUnknownImpl { - fn Close(&self) -> windows_core::Result<()>; - } - impl IClosable_Vtbl { - pub const fn new() -> Self { - unsafe extern "system" fn Close( - this: *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IClosable_Impl::Close(this).into() - } - Self { - base__: windows_core::IInspectable_Vtbl::new::(), - Close: Close::, - } - } - pub fn matches(iid: &windows_core::GUID) -> bool { - iid == &::IID - } - } - #[repr(C)] - pub struct IClosable_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub Close: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, - } windows_core::imp::define_interface!( IMemoryBuffer, IMemoryBuffer_Vtbl, @@ -76,7 +22,10 @@ pub mod Windows { windows_core::IUnknown, windows_core::IInspectable ); - windows_core::imp::required_hierarchy!(IMemoryBuffer, IClosable); + windows_core::imp::required_hierarchy!( + IMemoryBuffer, + crate::reference_dependency_flat::IClosable + ); impl IMemoryBuffer { pub fn CreateReference( &self, @@ -93,7 +42,9 @@ pub mod Windows { } } pub fn Close(&self) -> windows_core::Result<()> { - let this = &windows_core::Interface::cast::(self)?; + let this = &windows_core::Interface::cast::< + crate::reference_dependency_flat::IClosable, + >(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw( this, @@ -105,7 +56,7 @@ pub mod Windows { impl windows_core::RuntimeName for IMemoryBuffer { const NAME: &'static str = "Windows.Foundation.IMemoryBuffer"; } - pub trait IMemoryBuffer_Impl: IClosable_Impl { + pub trait IMemoryBuffer_Impl: crate::reference_dependency_flat::IClosable_Impl { fn CreateReference( &self, ) -> windows_core::Result; diff --git a/crates/tests/bindgen/src/reference_dependent_full.rs b/crates/tests/bindgen/src/reference_dependent_full.rs index f5628f1757..55ec704059 100644 --- a/crates/tests/bindgen/src/reference_dependent_full.rs +++ b/crates/tests/bindgen/src/reference_dependent_full.rs @@ -8,60 +8,6 @@ pub mod Windows { pub mod Foundation { - windows_core::imp::define_interface!( - IClosable, - IClosable_Vtbl, - 0x30d5a829_7fa4_4026_83bb_d75bae4ea99e - ); - impl windows_core::RuntimeType for IClosable { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_interface::(); - } - windows_core::imp::interface_hierarchy!( - IClosable, - windows_core::IUnknown, - windows_core::IInspectable - ); - impl IClosable { - pub fn Close(&self) -> windows_core::Result<()> { - let this = self; - unsafe { - (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw( - this, - )) - .ok() - } - } - } - impl windows_core::RuntimeName for IClosable { - const NAME: &'static str = "Windows.Foundation.IClosable"; - } - pub trait IClosable_Impl: windows_core::IUnknownImpl { - fn Close(&self) -> windows_core::Result<()>; - } - impl IClosable_Vtbl { - pub const fn new() -> Self { - unsafe extern "system" fn Close( - this: *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IClosable_Impl::Close(this).into() - } - Self { - base__: windows_core::IInspectable_Vtbl::new::(), - Close: Close::, - } - } - pub fn matches(iid: &windows_core::GUID) -> bool { - iid == &::IID - } - } - #[repr(C)] - pub struct IClosable_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub Close: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, - } windows_core::imp::define_interface!( IMemoryBuffer, IMemoryBuffer_Vtbl, @@ -76,7 +22,10 @@ pub mod Windows { windows_core::IUnknown, windows_core::IInspectable ); - windows_core::imp::required_hierarchy!(IMemoryBuffer, IClosable); + windows_core::imp::required_hierarchy!( + IMemoryBuffer, + crate::reference_dependency_full::Windows::Foundation::IClosable + ); impl IMemoryBuffer { pub fn CreateReference( &self, @@ -94,7 +43,9 @@ pub mod Windows { } } pub fn Close(&self) -> windows_core::Result<()> { - let this = &windows_core::Interface::cast::(self)?; + let this = &windows_core::Interface::cast::< + crate::reference_dependency_full::Windows::Foundation::IClosable, + >(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw( this, @@ -106,7 +57,9 @@ pub mod Windows { impl windows_core::RuntimeName for IMemoryBuffer { const NAME: &'static str = "Windows.Foundation.IMemoryBuffer"; } - pub trait IMemoryBuffer_Impl: IClosable_Impl { + pub trait IMemoryBuffer_Impl: + crate::reference_dependency_full::Windows::Foundation::IClosable_Impl + { fn CreateReference( &self, ) -> windows_core::Result< diff --git a/crates/tests/bindgen/src/reference_dependent_skip_root.rs b/crates/tests/bindgen/src/reference_dependent_skip_root.rs index 089e7346d1..53c630f743 100644 --- a/crates/tests/bindgen/src/reference_dependent_skip_root.rs +++ b/crates/tests/bindgen/src/reference_dependent_skip_root.rs @@ -8,60 +8,6 @@ pub mod Windows { pub mod Foundation { - windows_core::imp::define_interface!( - IClosable, - IClosable_Vtbl, - 0x30d5a829_7fa4_4026_83bb_d75bae4ea99e - ); - impl windows_core::RuntimeType for IClosable { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_interface::(); - } - windows_core::imp::interface_hierarchy!( - IClosable, - windows_core::IUnknown, - windows_core::IInspectable - ); - impl IClosable { - pub fn Close(&self) -> windows_core::Result<()> { - let this = self; - unsafe { - (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw( - this, - )) - .ok() - } - } - } - impl windows_core::RuntimeName for IClosable { - const NAME: &'static str = "Windows.Foundation.IClosable"; - } - pub trait IClosable_Impl: windows_core::IUnknownImpl { - fn Close(&self) -> windows_core::Result<()>; - } - impl IClosable_Vtbl { - pub const fn new() -> Self { - unsafe extern "system" fn Close( - this: *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IClosable_Impl::Close(this).into() - } - Self { - base__: windows_core::IInspectable_Vtbl::new::(), - Close: Close::, - } - } - pub fn matches(iid: &windows_core::GUID) -> bool { - iid == &::IID - } - } - #[repr(C)] - pub struct IClosable_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub Close: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, - } windows_core::imp::define_interface!( IMemoryBuffer, IMemoryBuffer_Vtbl, @@ -76,7 +22,10 @@ pub mod Windows { windows_core::IUnknown, windows_core::IInspectable ); - windows_core::imp::required_hierarchy!(IMemoryBuffer, IClosable); + windows_core::imp::required_hierarchy!( + IMemoryBuffer, + crate::reference_dependency_skip_root::Windows::Foundation::IClosable + ); impl IMemoryBuffer { pub fn CreateReference( &self, @@ -94,7 +43,9 @@ pub mod Windows { } } pub fn Close(&self) -> windows_core::Result<()> { - let this = &windows_core::Interface::cast::(self)?; + let this = &windows_core::Interface::cast::< + crate::reference_dependency_skip_root::Windows::Foundation::IClosable, + >(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw( this, @@ -106,7 +57,9 @@ pub mod Windows { impl windows_core::RuntimeName for IMemoryBuffer { const NAME: &'static str = "Windows.Foundation.IMemoryBuffer"; } - pub trait IMemoryBuffer_Impl: IClosable_Impl { + pub trait IMemoryBuffer_Impl: + crate::reference_dependency_skip_root::Windows::Foundation::IClosable_Impl + { fn CreateReference( &self, ) -> windows_core::Result< diff --git a/crates/tests/bindgen/src/reference_windows.rs b/crates/tests/bindgen/src/reference_windows.rs deleted file mode 100644 index f8e1728c2f..0000000000 --- a/crates/tests/bindgen/src/reference_windows.rs +++ /dev/null @@ -1,151 +0,0 @@ -#![allow( - non_snake_case, - non_upper_case_globals, - non_camel_case_types, - dead_code, - clippy::all -)] - -pub mod Windows { - pub mod Foundation { - windows_core::imp::define_interface!( - IClosable, - IClosable_Vtbl, - 0x30d5a829_7fa4_4026_83bb_d75bae4ea99e - ); - impl windows_core::RuntimeType for IClosable { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_interface::(); - } - windows_core::imp::interface_hierarchy!( - IClosable, - windows_core::IUnknown, - windows_core::IInspectable - ); - impl IClosable { - pub fn Close(&self) -> windows_core::Result<()> { - let this = self; - unsafe { - (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw( - this, - )) - .ok() - } - } - } - impl windows_core::RuntimeName for IClosable { - const NAME: &'static str = "Windows.Foundation.IClosable"; - } - pub trait IClosable_Impl: windows_core::IUnknownImpl { - fn Close(&self) -> windows_core::Result<()>; - } - impl IClosable_Vtbl { - pub const fn new() -> Self { - unsafe extern "system" fn Close( - this: *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IClosable_Impl::Close(this).into() - } - Self { - base__: windows_core::IInspectable_Vtbl::new::(), - Close: Close::, - } - } - pub fn matches(iid: &windows_core::GUID) -> bool { - iid == &::IID - } - } - #[repr(C)] - pub struct IClosable_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub Close: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, - } - windows_core::imp::define_interface!( - IMemoryBuffer, - IMemoryBuffer_Vtbl, - 0xfbc4dd2a_245b_11e4_af98_689423260cf8 - ); - impl windows_core::RuntimeType for IMemoryBuffer { - const SIGNATURE: windows_core::imp::ConstBuffer = - windows_core::imp::ConstBuffer::for_interface::(); - } - windows_core::imp::interface_hierarchy!( - IMemoryBuffer, - windows_core::IUnknown, - windows_core::IInspectable - ); - windows_core::imp::required_hierarchy!(IMemoryBuffer, IClosable); - impl IMemoryBuffer { - pub fn CreateReference( - &self, - ) -> windows_core::Result { - let this = self; - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(this).CreateReference)( - windows_core::Interface::as_raw(this), - &mut result__, - ) - .and_then(|| windows_core::Type::from_abi(result__)) - } - } - pub fn Close(&self) -> windows_core::Result<()> { - let this = &windows_core::Interface::cast::(self)?; - unsafe { - (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw( - this, - )) - .ok() - } - } - } - impl windows_core::RuntimeName for IMemoryBuffer { - const NAME: &'static str = "Windows.Foundation.IMemoryBuffer"; - } - pub trait IMemoryBuffer_Impl: IClosable_Impl { - fn CreateReference( - &self, - ) -> windows_core::Result; - } - impl IMemoryBuffer_Vtbl { - pub const fn new() -> Self { - unsafe extern "system" fn CreateReference< - Identity: IMemoryBuffer_Impl, - const OFFSET: isize, - >( - this: *mut core::ffi::c_void, - result__: *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT { - let this: &Identity = - &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IMemoryBuffer_Impl::CreateReference(this) { - Ok(ok__) => { - result__.write(core::mem::transmute_copy(&ok__)); - core::mem::forget(ok__); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - Self { - base__: windows_core::IInspectable_Vtbl::new::( - ), - CreateReference: CreateReference::, - } - } - pub fn matches(iid: &windows_core::GUID) -> bool { - iid == &::IID - } - } - #[repr(C)] - pub struct IMemoryBuffer_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub CreateReference: unsafe extern "system" fn( - *mut core::ffi::c_void, - *mut *mut core::ffi::c_void, - ) -> windows_core::HRESULT, - } - } -} diff --git a/crates/tests/winrt/reference/Cargo.toml b/crates/tests/winrt/reference/Cargo.toml new file mode 100644 index 0000000000..7f90dd9c30 --- /dev/null +++ b/crates/tests/winrt/reference/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "test_reference" +version = "0.0.0" +edition = "2021" +publish = false + +[lib] +crate-type = ["cdylib"] +doc = false +doctest = false + +[build-dependencies.windows-bindgen] +workspace = true + +[dependencies.windows-core] +workspace = true + +[dependencies.windows] +workspace = true +features = [ + "Foundation", + "Win32_System_WinRT", +] diff --git a/crates/tests/winrt/reference/build.rs b/crates/tests/winrt/reference/build.rs new file mode 100644 index 0000000000..a23c8522df --- /dev/null +++ b/crates/tests/winrt/reference/build.rs @@ -0,0 +1,35 @@ +fn main() { + let mut command = std::process::Command::new("midlrt.exe"); + command.args([ + "/winrt", + "/nomidl", + "/h", + "nul", + "/metadata_dir", + "../../../libs/bindgen/default", + "/reference", + "../../../libs/bindgen/default/Windows.winmd", + "/winmd", + "metadata.winmd", + "src/metadata.idl", + ]); + + if !command.status().unwrap().success() { + panic!("Failed to run midlrt"); + } + + windows_bindgen::bindgen([ + "--in", + "metadata.winmd", + "../../../libs/bindgen/default", + "--out", + "src/bindings.rs", + "--filter", + "test_reference", + "--implement", + "--no-comment", + "--flat", + "--reference", + "windows,skip-root,Windows", + ]); +} diff --git a/crates/tests/winrt/reference/src/bindings.rs b/crates/tests/winrt/reference/src/bindings.rs new file mode 100644 index 0000000000..56e2a81bfc --- /dev/null +++ b/crates/tests/winrt/reference/src/bindings.rs @@ -0,0 +1,126 @@ +#![allow( + non_snake_case, + non_upper_case_globals, + non_camel_case_types, + dead_code, + clippy::all +)] + +windows_core::imp::define_interface!( + IReference, + IReference_Vtbl, + 0xdb426a55_0a8f_5cd8_8618_2926436cb7e6 +); +impl windows_core::RuntimeType for IReference { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IReference { + const NAME: &'static str = "test_reference.IReference"; +} +pub trait IReference_Impl: windows_core::IUnknownImpl { + fn Method( + &self, + stringable: Option<&windows::Foundation::IStringable>, + ) -> windows_core::Result; +} +impl IReference_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Method( + this: *mut core::ffi::c_void, + stringable: *mut core::ffi::c_void, + result__: *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IReference_Impl::Method(this, windows_core::from_raw_borrowed(&stringable)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Method: Method::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +pub struct IReference_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Method: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut core::ffi::c_void, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct Reference(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!( + Reference, + windows_core::IUnknown, + windows_core::IInspectable +); +windows_core::imp::required_hierarchy!(Reference, windows::Foundation::IStringable); +impl Reference { + pub fn new() -> windows_core::Result { + Self::IActivationFactory(|f| f.ActivateInstance::()) + } + fn IActivationFactory< + R, + F: FnOnce(&windows_core::imp::IGenericFactory) -> windows_core::Result, + >( + callback: F, + ) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache< + Reference, + windows_core::imp::IGenericFactory, + > = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + pub fn Method(&self, stringable: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Method)( + windows_core::Interface::as_raw(this), + stringable.param().abi(), + &mut result__, + ) + .map(|| core::mem::transmute(result__)) + } + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| core::mem::transmute(result__)) + } + } +} +impl windows_core::RuntimeType for Reference { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for Reference { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for Reference { + const NAME: &'static str = "test_reference.Reference"; +} +unsafe impl Send for Reference {} +unsafe impl Sync for Reference {} diff --git a/crates/tests/winrt/reference/src/lib.rs b/crates/tests/winrt/reference/src/lib.rs new file mode 100644 index 0000000000..b02e0b65e6 --- /dev/null +++ b/crates/tests/winrt/reference/src/lib.rs @@ -0,0 +1,40 @@ +mod bindings; + +use windows::{core::*, Foundation::*, Win32::Foundation::*, Win32::System::WinRT::*}; + +#[no_mangle] +unsafe extern "system" fn DllGetActivationFactory( + name: Ref, + factory: OutRef, +) -> HRESULT { + if *name == "test_reference.Reference" { + factory.write(Some(ReferenceFactory.into())).into() + } else { + _ = factory.write(None); + CLASS_E_CLASSNOTAVAILABLE + } +} + +#[implement(IActivationFactory)] +struct ReferenceFactory; + +impl IActivationFactory_Impl for ReferenceFactory_Impl { + fn ActivateInstance(&self) -> Result { + Ok(Reference.into()) + } +} + +#[implement(IStringable, bindings::IReference)] +struct Reference; + +impl IStringable_Impl for Reference_Impl { + fn ToString(&self) -> Result { + Ok(h!("Reference").clone()) + } +} + +impl bindings::IReference_Impl for Reference_Impl { + fn Method(&self, stringable: Option<&IStringable>) -> Result { + stringable.unwrap().ToString() + } +} diff --git a/crates/tests/winrt/reference/src/metadata.idl b/crates/tests/winrt/reference/src/metadata.idl new file mode 100644 index 0000000000..3782502f0d --- /dev/null +++ b/crates/tests/winrt/reference/src/metadata.idl @@ -0,0 +1,8 @@ +namespace test_reference +{ + runtimeclass Reference : Windows.Foundation.IStringable + { + Reference(); + String Method(Windows.Foundation.IStringable stringable); + } +} diff --git a/crates/tests/winrt/reference_client/Cargo.toml b/crates/tests/winrt/reference_client/Cargo.toml new file mode 100644 index 0000000000..a2acfe04c5 --- /dev/null +++ b/crates/tests/winrt/reference_client/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "test_reference_client" +version = "0.0.0" +edition = "2021" +publish = false + +[lib] +doc = false +doctest = false + +[build-dependencies.windows-bindgen] +workspace = true + +[dependencies.windows-core] +workspace = true + +[dependencies.windows] +workspace = true +features = [ + "Foundation", + "Win32_Foundation", +] + +# The build needs the output (.dll) of the component. This causes a warning about lack of linkage target. +# Cargo doesn't understand cdylib targets. https://github.com/rust-lang/cargo/issues/7825 +[dependencies.test_reference] +path = "../reference" diff --git a/crates/tests/winrt/reference_client/build.rs b/crates/tests/winrt/reference_client/build.rs new file mode 100644 index 0000000000..55ddd26a2f --- /dev/null +++ b/crates/tests/winrt/reference_client/build.rs @@ -0,0 +1,15 @@ +fn main() { + windows_bindgen::bindgen([ + "--in", + "../reference/metadata.winmd", + "../../../libs/bindgen/default", + "--out", + "src/bindings.rs", + "--filter", + "test_reference", + "--no-comment", + "--flat", + "--reference", + "windows,skip-root,Windows", + ]); +} diff --git a/crates/tests/winrt/reference_client/src/bindings.rs b/crates/tests/winrt/reference_client/src/bindings.rs new file mode 100644 index 0000000000..d9cb059b50 --- /dev/null +++ b/crates/tests/winrt/reference_client/src/bindings.rs @@ -0,0 +1,91 @@ +#![allow( + non_snake_case, + non_upper_case_globals, + non_camel_case_types, + dead_code, + clippy::all +)] + +windows_core::imp::define_interface!( + IReference, + IReference_Vtbl, + 0xdb426a55_0a8f_5cd8_8618_2926436cb7e6 +); +impl windows_core::RuntimeType for IReference { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_interface::(); +} +#[repr(C)] +pub struct IReference_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Method: unsafe extern "system" fn( + *mut core::ffi::c_void, + *mut core::ffi::c_void, + *mut *mut core::ffi::c_void, + ) -> windows_core::HRESULT, +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct Reference(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!( + Reference, + windows_core::IUnknown, + windows_core::IInspectable +); +windows_core::imp::required_hierarchy!(Reference, windows::Foundation::IStringable); +impl Reference { + pub fn new() -> windows_core::Result { + Self::IActivationFactory(|f| f.ActivateInstance::()) + } + fn IActivationFactory< + R, + F: FnOnce(&windows_core::imp::IGenericFactory) -> windows_core::Result, + >( + callback: F, + ) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache< + Reference, + windows_core::imp::IGenericFactory, + > = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + pub fn Method(&self, stringable: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Method)( + windows_core::Interface::as_raw(this), + stringable.param().abi(), + &mut result__, + ) + .map(|| core::mem::transmute(result__)) + } + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)( + windows_core::Interface::as_raw(this), + &mut result__, + ) + .map(|| core::mem::transmute(result__)) + } + } +} +impl windows_core::RuntimeType for Reference { + const SIGNATURE: windows_core::imp::ConstBuffer = + windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for Reference { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for Reference { + const NAME: &'static str = "test_reference.Reference"; +} +unsafe impl Send for Reference {} +unsafe impl Sync for Reference {} diff --git a/crates/tests/winrt/reference_client/src/lib.rs b/crates/tests/winrt/reference_client/src/lib.rs new file mode 100644 index 0000000000..73c189db37 --- /dev/null +++ b/crates/tests/winrt/reference_client/src/lib.rs @@ -0,0 +1,13 @@ +#![cfg(test)] + +mod bindings; +use bindings::*; +use windows::core::*; + +#[test] +fn test() -> Result<()> { + let reference = Reference::new()?; + assert_eq!(reference.ToString()?, "Reference"); + assert_eq!(reference.Method(&reference)?, "Reference"); + Ok(()) +} diff --git a/crates/tools/bindgen/src/main.rs b/crates/tools/bindgen/src/main.rs index 8874ddf77e..38be60948b 100644 --- a/crates/tools/bindgen/src/main.rs +++ b/crates/tools/bindgen/src/main.rs @@ -122,7 +122,12 @@ fn main() { test("--out window_long_set_w_sys.rs --filter SetWindowLongPtrW --sys"); // Tests for external references e.g. references to other crates - test_raw("--no-comment --out reference_windows.rs --filter IMemoryBuffer --reference windows,skip-root,IMemoryBufferReference"); + test("--out reference_async_info_no_status.rs --filter IAsyncInfo"); + test("--out reference_async_info_status_filter.rs --filter IAsyncInfo AsyncStatus"); + test("--out reference_async_info_status_reference.rs --filter IAsyncInfo --reference windows,skip-root,AsyncStatus"); + test("--out reference_async_action.rs --filter IAsyncAction"); + test("--out reference_async_action_reference.rs --filter IAsyncAction --reference windows,skip-root,IAsyncInfo"); + test_raw( "--no-comment --out reference_dependency_flat.rs --filter IMemoryBufferReference --flat", );