You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Rust的windows crate调用EnumPrintersA获取PRINTER_INFO_4A列表

Rust调用EnumPrintersA获取PRINTER_INFO_4A列表

实现步骤与代码示例

EnumPrintersA需要分两次调用完成数据获取:先获取所需缓冲区大小,再分配内存读取实际打印机信息。以下是完整实现:

use windows::Win32::Graphics::Printing::{EnumPrintersA, PRINTER_INFO_4A};
use windows::Win32::Foundation::PCSTR;
use windows_core::Result;

fn get_printer_info_list() -> Result<Vec<PRINTER_INFO_4A>> {
    unsafe {
        // 1. 首次调用:获取所需缓冲区大小
        let mut pcbneeded = 0;
        // 传入null参数触发返回所需大小,忽略返回的打印机数量
        EnumPrintersA(
            2, // PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS
            PCSTR::null(),
            4, // 指定获取PRINTER_INFO_4A结构
            None, // 缓冲区传None对应null指针
            &mut pcbneeded,
            std::ptr::null_mut(), // 数量参数传null
        )?;

        // 根据返回的大小分配缓冲区
        let mut buffer = vec![0u8; pcbneeded as usize];

        // 2. 二次调用:获取实际打印机数据
        let mut pcbreturned = 0;
        EnumPrintersA(
            2,
            PCSTR::null(),
            4,
            Some(&mut buffer), // 传入分配好的可变缓冲区
            &mut pcbneeded,
            &mut pcbreturned,
        )?;

        // 将字节缓冲区转换为PRINTER_INFO_4A切片
        let info_slice = std::slice::from_raw_parts(
            buffer.as_ptr() as *const PRINTER_INFO_4A,
            pcbreturned as usize,
        );

        // 转换为Vec返回
        Ok(info_slice.to_vec())
    }
}

fn main() -> Result<()> {
    let printers = get_printer_info_list()?;
    for (i, printer) in printers.iter().enumerate() {
        println!("打印机 {}: {:?}", i + 1, printer.pPrinterName);
    }
    Ok(())
}

关键细节解答

1. 变量声明要点

  • pcbneeded:u32类型,用于存储API返回的所需缓冲区字节数。
  • pcbreturned:u32类型,存储实际返回的PRINTER_INFO_4A结构体数量。
  • buffer:Vec<u8>,自动管理内存的缓冲区,首次调用后根据pcbneeded动态分配大小。

2. 两次调用的参数传递规则

  • 首次调用:
    • name:传PCSTR::null(),配合flags=2枚举本地和已连接打印机。
    • pprinterenum:传None,对应C语言的NULL指针,告诉API只返回所需缓冲区大小。
    • pcreturned:传std::ptr::null_mut(),首次调用不需要返回打印机数量。
  • 二次调用:
    • pprinterenum:传Some(&mut buffer),将分配好的可变字节缓冲区传给API。
    • pcreturned:传&mut pcbreturned的指针,用于接收返回的打印机数量。

3. 缓冲区转换为目标结构体

利用std::slice::from_raw_parts将字节缓冲区的指针转换为PRINTER_INFO_4A类型的切片,再通过to_vec()转换为Vec<PRINTER_INFO_4A>,完成类型安全的转换。

内容的提问来源于stack exchange,提问作者e-Ra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 14:20:01