键盘快捷键

在章节间导航

S/ 在书中搜索

? 显示此帮助

Esc 隐藏此帮助

如何查询特定的 COM 接口?

windows crate 中的 COM 和 WinRT 接口实现了 ComInterface trait。此 trait 提供了 cast 方法,该方法将在底层使用 QueryInterface 将当前接口转换为对象支持的另一个接口。cast 方法返回 Result<T>,因此在 Rust 中可以以自然的方式处理失败。

例如,通常需要获取给定 Direct3D 设备的 IDXGIDevice 接口,以便与其他渲染 API 进行互操作。以下是您可能为 Direct3D 设备创建用于绘图和呈现的交换链的方法。让我们想象一个简单的函数,它接受一个 Direct3D 设备并返回底层的 DXGI 工厂

#![allow(unused)]
fn main() {
fn get_dxgi_factory(device: &ID3D11Device) -> Result<IDXGIFactory2> {
}
}

您首先需要做的是查询或将 Direct3D 设备转换为其 DXGI 接口,如下所示

#![allow(unused)]
fn main() {
let device = device.cast::<IDXGIDevice>()?;
}

如果更方便,您也可以利用类型推断,如下所示

#![allow(unused)]
fn main() {
let device: IDXGIDevice = device.cast()?;
}

有了 COM 接口,我们需要一个 unsafe 块来调用它的方法

#![allow(unused)]
fn main() {
unsafe {
}
}

unsafe 块中,我们可以检索设备的物理适配器

#![allow(unused)]
fn main() {
let adapter = device.GetAdapter()?;
}

仅仅为了好玩(或调试),我们可能会打印出适配器的名称

#![allow(unused)]
fn main() {
if cfg!(debug_assertions) {
    let mut desc = Default::default();
    adapter.GetDesc(&mut desc)?;
    println!("{}", String::from_utf16_lossy(&desc.Description));
}
}

最后,我们可以返回适配器的父级以及设备的 DXGI 工厂对象

#![allow(unused)]
fn main() {
adapter.GetParent()
}

运行示例后,我得到了以下令人印象深刻的结果

AMD FirePro W4100

这里有一个更全面的 DirectX 示例

cast 方法对 WinRT 类和接口同样适用。它对于与 WinRT API 的互操作特别有用。