I'm trying to use the Win32 API go get a list of windows that match a certain window title. For that I have written a method that uses the windows-rs crate to call the required system functions
fn enumerate_windows(enum_func: impl FnMut(&Process, &Window) -> bool) -> bool {
let lparam = type_to_isize(&enum_func);
unsafe { EnumWindows(Some(enum_windows_proc), LPARAM(lparam)) }.into()
}
The enum_windows_proc
function passed to the EnumWindows
function has the signature unsafe extern "system" fn enum_windows_proc(hwnd: HWND, param: LPARAM) -> BOOL
. So far so good.
The enumerate_windows
function is called from another function:
pub(crate) fn get_results<'a> (players: &'a Vec<MediaPlayer>, media_proc: &MediaProcT, results: &mut Vec<Result<'a>>) -> bool {
let window_proc = |process:&'static Process, window:&'static Window| {
for player in players {
// Test if the give player is recognized media player
if is_media_player_window(process, window, player) {
let result = Result {
player: player,
process: process,
window: window,
media: Vec::new(),
};
results.push(result);
return true;
}
}
false
};
if !enumerate_windows(window_proc) {
false
} else {
true
}
}
However, when I try to compile, rustc spits out these errors:
error[E0308]: mismatched types
--> src\platform.rs:56:9
|
56 | if !enumerate_windows(window_proc) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected traitfor<'a, 'b> FnMut<(&'a Process, &'b Window)>
found traitFnMut<(&Process, &Window)>
note: this closure does not fulfill the lifetime requirements
--> src\platform.rs:39:23
|
39 | let window_proc = |process:&'static Process, window:&'static Window| {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: the lifetime requirement is introduced here
--> src\windows.rs:30:49
|
30 | pub(crate) fn enumerate_windows(enum_func: impl FnMut(&Process, &Window) -> bool) -> bool {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^error: implementation of
FnOnce
is not general enough
--> src\platform.rs:56:9
|
56 | if !enumerate_windows(window_proc) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation ofFnOnce
is not general enough
|
= note: closure with signaturefn(&'2 Process, &Window) -> bool
must implementFnOnce<(&'1 Process, &Window)>
, for any lifetime'1
...
= note: ...but it actually implementsFnOnce<(&'2 Process, &Window)>
, for some specific lifetime'2
error: implementation of
FnOnce
is not general enough
--> src\platform.rs:56:9
|
56 | if !enumerate_windows(window_proc) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation ofFnOnce
is not general enough
|
= note: closure with signaturefn(&Process, &'2 Window) -> bool
must implementFnOnce<(&Process, &'1 Window)>
, for any lifetime'1
...
= note: ...but it actually implementsFnOnce<(&Process, &'2 Window)>
, for some specific lifetime'2
I have seen rust - Why does passing a closure to function which accepts a function pointer not work? - Stack Overflow on SO and according to that advice set the type of the input parameter for enumerate_windows
accordingly.
What did I miss? Is it just a lifetime annotation?