使用Windows API枚举窗口时传递LPARAM遇类型转换错误
问题解决:Rust中向Windows API EnumWindows传递Vec作为LPARAM
错误原因
Rust不允许直接将非原始类型的指针(比如*mut Vec<isize>)强制转换为LPARAM——LPARAM本质是原始整数类型(Windows架构下对应isize或usize),而*mut Vec<isize>属于复合类型指针,直接用as转换会触发类型检查限制。
正确实现方式
1. 调整指针转换逻辑
先把*mut Vec<isize>转换为通用空指针*mut c_void,再转换为LPARAM——c_void指针属于原始类型范畴,可合法完成转换。
2. 完整代码示例
use windows::Win32::UI::WindowsAndMessaging::{EnumWindows, EnumWindowsProc, HWND, LPARAM}; use std::ptr; unsafe extern "system" fn enum_window(hwnd: HWND, lparam: LPARAM) -> bool { // 将LPARAM转换回*mut Vec<isize> let windows = lparam as *mut Vec<isize>; // 将HWND转为isize存入Vec (*windows).push(hwnd.0 as isize); true // 返回true继续枚举所有窗口 } fn main() { unsafe { let mut windows: Vec<isize> = vec![]; // 分两步完成指针到LPARAM的转换 let lparam = &mut windows as *mut Vec<isize> as *mut std::ffi::c_void as LPARAM; let _ = EnumWindows(Some(enum_window), lparam).ok(); // 示例:打印枚举到的窗口句柄 for hwnd in windows { println!("窗口句柄: {}", hwnd); } } }
3. 关键注意点
- 回调函数中必须保证
LPARAM转换回的指针有效:要确保EnumWindows执行期间,windows的生命周期未结束(示例中main函数里的windows在枚举完成后才离开作用域,符合安全要求)。 - 回调函数必须使用
extern "system"调用约定,匹配Windows API的回调规范。 HWND的内部字段0是原始整数类型,可直接转换为isize存入Vec。
内容的提问来源于stack exchange,提问作者YummyOreo
相关产品推荐
相关产品推荐

