Skip to content

Commit

Permalink
Fix and test for bindgen for methods and functions that have a traili…
Browse files Browse the repository at this point in the history
…ng array parameter that is confused for a result value and returned as such.
  • Loading branch information
iancormac84 committed Dec 22, 2024
1 parent 20af225 commit 3c9db4d
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 1 deletion.
2 changes: 1 addition & 1 deletion crates/libs/bindgen/src/types/cpp_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
129 changes: 129 additions & 0 deletions crates/tests/bindgen/src/interface_array_return.rs
Original file line number Diff line number Diff line change
@@ -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<u32> {
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<u32>;
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<Identity: IDispatch_Impl, const OFFSET: isize>() -> 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<Identity: IDispatch_Impl, const OFFSET: isize>(
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::<Identity, OFFSET>(),
GetTypeInfoCount: GetTypeInfoCount::<Identity, OFFSET>,
GetTypeInfo: 0,
GetIDsOfNames: GetIDsOfNames::<Identity, OFFSET>,
Invoke: 0,
}
}
pub fn matches(iid: &windows_core::GUID) -> bool {
iid == &<IDispatch as windows_core::Interface>::IID
}
}
impl windows_core::RuntimeName for IDispatch {}
1 change: 1 addition & 0 deletions crates/tests/bindgen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions crates/tools/bindgen/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down

0 comments on commit 3c9db4d

Please sign in to comment.