Rust中调用GetExitCodeProcess的内存错误及相关技术疑问
关于进程循环操作与GetExitCodeProcess的疑问解答
1. 两种写法结果不同的原因
Windows API GetExitCodeProcess的第二个参数要求是指向可写、已分配内存区域的LPDWORD(即*mut u32):
- 首次写法若使用未初始化的单个
u32变量(比如let mut exit_code: u32;),虽然Rust允许获取其可变引用,但编译器的栈布局优化可能导致该内存区域被标记为不可写,或因未初始化内存的不确定性触发STATUS_ACCESS_VIOLATION;若误传不可变引用或空指针,也会直接引发访问错误。 - 改用数组
let mut exit_code = [0u32; 1]时,数组会在栈上分配并初始化一块确定的可写内存,传递其指针(或可变引用)时,API能安全写入数据,因此不会出现访问违规。
2. 更优的存储方式
完全不需要用数组,直接使用初始化好的单个u32变量是最直观高效的写法:
use winapi::um::processthreadsapi::GetExitCodeProcess; use winapi::shared::minwindef::DWORD; // 假设已持有合法的process_handle let mut exit_code: DWORD = 0; unsafe { if GetExitCodeProcess(process_handle, &mut exit_code) { // 处理退出码逻辑 } }
若追求极致性能(实际没必要,u32初始化开销可忽略),也可以用std::mem::MaybeUninit跳过初始化,但需确保后续API会写入数据:
use std::mem::MaybeUninit; use winapi::um::processthreadsapi::GetExitCodeProcess; use winapi::shared::minwindef::DWORD; let mut exit_code = MaybeUninit::<DWORD>::uninit(); unsafe { if GetExitCodeProcess(process_handle, exit_code.as_mut_ptr()) { let exit_code = exit_code.assume_init(); // 处理逻辑 } }
3. Rust中未自动关联STILL_ACTIVE的原因
STILL_ACTIVE是Windows原生定义的常量(值为259),Rust的win32相关crate(如winapi、windows-sys)已包含该常量。你所说的“C中将exit设为STILL_ACTIVE”其实是指C代码会显式用该常量判断进程状态,Rust的逻辑完全一致:当进程仍在运行时,GetExitCodeProcess会主动将输出参数设为STILL_ACTIVE,Rust只是忠实地传递API返回结果,不会额外做自动赋值。只需导入常量后显式判断即可:
use winapi::shared::minwindef::STILL_ACTIVE; // ... if exit_code == STILL_ACTIVE { // 进程仍在运行,执行循环操作 }
内容的提问来源于stack exchange,提问作者johnsc
相关产品推荐
相关产品推荐

