2 个版本

0.1.1 2024 年 4 月 30 日
0.1.0 2023 年 6 月 12 日

#912 in Rust 模式

每月 36 次下载
用于 vst3

MIT/Apache

43KB
754

com-scrape-types

Cargo Docs

支持由 com-scrape 生成的绑定。

许可证

com-scrape-types 在 MIT 许可证和 Apache 许可证(版本 2.0)的条款下分发。贡献也接受相同的条款。


lib.rs:

支持由 com-scrape 生成的绑定的类型和特征。

ComPtrComRef 是用于与 COM 对象交互(调用方法、在接口之间进行转换和管理引用计数)的智能指针。可以使用 Class 特征在 Rust 中定义 COM 类,ComWrapper 是用于实例化这些类的智能指针。

引用计数

COM 对象是引用计数的。尽可能自动管理 ComPtrComRef 智能指针,但 com-scrape 生成的函数签名仍然将 COM 对象作为原始指针传递,在转换边界时必须小心处理所有权的正确性问题。

在微软COM文档的“管理引用计数规则”页面(https://learn.microsoft.com/en-us/windows/win32/com/rules-for-managing-reference-counts)以及每个单独的ComPtrComRef方法文档中,可以找到如何在各种情况下管理COM对象的引用计数的详细概述。然而,以下经验法则在大多数情况下都适用。

  1. 当将接口指针作为函数参数传递时,使用ComPtr::as_ptrComPtr获取原始指针,或者使用ComRef::as_ptrComRef获取原始指针。

  2. 当接收一个函数的返回值(或通过out参数)作为接口指针时,始终使用ComPtr::from_raw从原始指针获取ComPtr

  3. 当接收一个函数参数作为接口指针时,始终使用ComRef::from_raw从原始指针获取ComRef。如果接收到的接口指针将超出当前函数的持续时间,使用ComRef::to_com_ptrComRef升级为ComPtr

  4. 当从函数返回接口指针(或通过out参数返回)时,始终使用ComPtr::into_rawComPtr获取原始指针。

在Rust中实现COM接口

可以使用Class特质在Rust中定义COM类,并使用ComWrapper智能指针来实例化这些类的对象。要定义COM类,首先定义一个Rust类型

struct MyClass { /* ... */ }

然后为该类型实现所需的接口特质

impl ISomeInterfaceTrait for MyClass {
    unsafe fn some_method(&self) {
        /* ... */
    }
}

impl IAnotherInterfaceTrait for MyClass {
    unsafe fn another_method(&self) {
        /* ... */
    }
}

最后,为该类型实现Class特质,指定COM接口集合为一个元组

impl Class for MyClass {
    type Interfaces = (ISomeInterface, IAnotherInterface);
}

有了这些定义,可以使用ComWrapper来实例化支持上述接口的COM对象

let my_obj = ComWrapper::new(MyClass);

let ptr = my_obj.to_com_ptr::<ISomeInterface>().unwrap();
ptr.some_method();

let ptr = my_obj.to_com_ptr::<IAnotherInterface>().unwrap();
ptr.another_method();

无运行时依赖