From 3c9db4d61f4b92f5a568a71fcafccdc0a4a285b9 Mon Sep 17 00:00:00 2001 From: iancormac84 Date: Sat, 21 Dec 2024 22:05:07 -0400 Subject: [PATCH] Fix and test for bindgen for methods and functions that have a trailing array parameter that is confused for a result value and returned as such. --- crates/libs/bindgen/src/types/cpp_method.rs | 2 +- .../bindgen/src/interface_array_return.rs | 129 ++++++++++++++++++ crates/tests/bindgen/src/lib.rs | 1 + crates/tools/bindgen/src/main.rs | 1 + 4 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 crates/tests/bindgen/src/interface_array_return.rs diff --git a/crates/libs/bindgen/src/types/cpp_method.rs b/crates/libs/bindgen/src/types/cpp_method.rs index 02e20f4aa0..8bd368a807 100644 --- a/crates/libs/bindgen/src/types/cpp_method.rs +++ b/crates/libs/bindgen/src/types/cpp_method.rs @@ -825,7 +825,7 @@ fn is_param_retval(ty: &Type, param: Param, hint: ParamHint) -> bool { { return false; } - if hint.is_array() { + if ParamHint::from_param(param).is_array() { return false; } diff --git a/crates/tests/bindgen/src/interface_array_return.rs b/crates/tests/bindgen/src/interface_array_return.rs new file mode 100644 index 0000000000..5869e0d508 --- /dev/null +++ b/crates/tests/bindgen/src/interface_array_return.rs @@ -0,0 +1,129 @@ +#![allow( + non_snake_case, + non_upper_case_globals, + non_camel_case_types, + dead_code, + clippy::all +)] + +windows_core::imp::define_interface!( + IDispatch, + IDispatch_Vtbl, + 0x00020400_0000_0000_c000_000000000046 +); +windows_core::imp::interface_hierarchy!(IDispatch, windows_core::IUnknown); +impl IDispatch { + pub unsafe fn GetTypeInfoCount(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetTypeInfoCount)( + windows_core::Interface::as_raw(self), + &mut result__, + ) + .map(|| result__) + } + } + pub unsafe fn GetIDsOfNames( + &self, + riid: *const windows_core::GUID, + rgsznames: *const windows_core::PCWSTR, + cnames: u32, + lcid: u32, + rgdispid: *mut i32, + ) -> windows_core::Result<()> { + unsafe { + (windows_core::Interface::vtable(self).GetIDsOfNames)( + windows_core::Interface::as_raw(self), + riid, + rgsznames, + cnames, + lcid, + core::mem::transmute(rgdispid), + ) + .ok() + } + } +} +#[repr(C)] +pub struct IDispatch_Vtbl { + pub base__: windows_core::IUnknown_Vtbl, + pub GetTypeInfoCount: + unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + GetTypeInfo: usize, + pub GetIDsOfNames: unsafe extern "system" fn( + *mut core::ffi::c_void, + *const windows_core::GUID, + *const windows_core::PCWSTR, + u32, + u32, + *mut i32, + ) -> windows_core::HRESULT, + Invoke: usize, +} +pub trait IDispatch_Impl: windows_core::IUnknownImpl { + fn GetTypeInfoCount(&self) -> windows_core::Result; + fn GetIDsOfNames( + &self, + riid: *const windows_core::GUID, + rgsznames: *const windows_core::PCWSTR, + cnames: u32, + lcid: u32, + rgdispid: *mut i32, + ) -> windows_core::Result<()>; +} +impl IDispatch_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetTypeInfoCount< + Identity: IDispatch_Impl, + const OFFSET: isize, + >( + this: *mut core::ffi::c_void, + pctinfo: *mut u32, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDispatch_Impl::GetTypeInfoCount(this) { + Ok(ok__) => { + pctinfo.write(core::mem::transmute(ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetIDsOfNames( + this: *mut core::ffi::c_void, + riid: *const windows_core::GUID, + rgsznames: *const windows_core::PCWSTR, + cnames: u32, + lcid: u32, + rgdispid: *mut i32, + ) -> windows_core::HRESULT { + unsafe { + let this: &Identity = + &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDispatch_Impl::GetIDsOfNames( + this, + core::mem::transmute_copy(&riid), + core::mem::transmute_copy(&rgsznames), + core::mem::transmute_copy(&cnames), + core::mem::transmute_copy(&lcid), + core::mem::transmute_copy(&rgdispid), + ) + .into() + } + } + Self { + base__: windows_core::IUnknown_Vtbl::new::(), + GetTypeInfoCount: GetTypeInfoCount::, + GetTypeInfo: 0, + GetIDsOfNames: GetIDsOfNames::, + Invoke: 0, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +impl windows_core::RuntimeName for IDispatch {} diff --git a/crates/tests/bindgen/src/lib.rs b/crates/tests/bindgen/src/lib.rs index 856a8c638d..a040b4abdf 100644 --- a/crates/tests/bindgen/src/lib.rs +++ b/crates/tests/bindgen/src/lib.rs @@ -45,6 +45,7 @@ pub mod fn_return_void_win; pub mod fn_sys; pub mod fn_win; pub mod interface; +pub mod interface_array_return; pub mod interface_cpp; pub mod interface_cpp_derive; pub mod interface_cpp_derive_sys; diff --git a/crates/tools/bindgen/src/main.rs b/crates/tools/bindgen/src/main.rs index cd60020028..28ada041ea 100644 --- a/crates/tools/bindgen/src/main.rs +++ b/crates/tools/bindgen/src/main.rs @@ -82,6 +82,7 @@ fn main() { test("--out interface_required_with_method.rs --filter IAsyncAction AsyncStatus"); test("--out interface_required_with_method_sys.rs --filter IAsyncAction AsyncStatus --sys"); test("--out interface_iterable.rs --filter IVector"); + test("--out interface_array_return.rs --filter IDispatch"); // Tests for functions test("--out fn_win.rs --filter GetTickCount");