如何查询特定的 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 的互操作特别有用。