Closed flaamjab closed 3 months ago
You have one reference too many:
DirectInput8Create
takes a *mut *mut c_void
(C++: void**
) as ppvout
while you're passing a *mut *mut IUnknown
= *mut *mut *mut c_void
(C++: void***
- remember that IUnknown
is a pointer already).
The following code doesn't segfault:
use std::{
ffi::c_void,
ptr::{self},
thread,
time::Duration,
};
use windows::{
core::{IUnknown, Interface},
Win32::{
Devices::HumanInterfaceDevice::{
DirectInput8Create, IDirectInput8W, DI8DEVCLASS_GAMECTRL, DIDEVICEINSTANCEW,
DIEDFL_ATTACHEDONLY, DIRECTINPUT_VERSION,
},
Foundation::{BOOL, HINSTANCE},
System::LibraryLoader::GetModuleHandleW,
},
};
fn main() {
unsafe {
let hinstance: HINSTANCE = GetModuleHandleW(None).unwrap().into();
assert_ne!(hinstance.0, 0);
let mut di8 = ptr::null_mut();
DirectInput8Create(
hinstance,
DIRECTINPUT_VERSION,
&IDirectInput8W::IID,
&mut di8,
None,
)
.unwrap();
assert!(!di8.is_null());
let di8 = IDirectInput8W::from_raw(di8);
di8.EnumDevices(
DI8DEVCLASS_GAMECTRL,
Some(di8_enumerate),
ptr::null_mut(),
DIEDFL_ATTACHEDONLY,
)
.unwrap();
}
}
unsafe extern "system" fn di8_enumerate(dev: *mut DIDEVICEINSTANCEW, param1: *mut c_void) -> BOOL {
true.into()
}
I think the metadata could be annotated here to make the generated code a bit nicer and harder to misuse.
That's illuminating. Thanks!
The metadata for DirectInput8Create
is not great. It might be possible to improve the bindings if you bring it up on the Win32 metadata repo.
Summary
Hello!
I'm attempting to use the DirectInput API through the
windows
crate (on Windows 10, Rust version 1.79) but have run into an issue with the program crashing when any method is called on the object returned fromDirectInput8Create
.The equivalent C++ code works though, and I don't know what I am missing, so I assume it might be an issue with the crate.
Crate manifest
Crate code