2 releases
0.1.1 | Apr 30, 2024 |
---|---|
0.1.0 | Jun 12, 2023 |
#1484 in Rust patterns
98 downloads per month
Used in 2 crates
(via vst3)
43KB
754 lines
com-scrape-types
Support code for bindings generated by com-scrape
.
License
com-scrape-types
is distributed under the terms of both the MIT license and the Apache license, version 2.0. Contributions are accepted under the same terms.
lib.rs
:
Support types and traits for bindings generated by com-scrape
.
ComPtr
and ComRef
are smart pointers for interacting with COM objects (calling methods,
casting between interfaces, and managing reference counts). The Class
trait can be used for
defining COM classes in Rust, and ComWrapper
is a smart pointer used for instantiating
those classes.
Reference counting
COM objects are reference-counted. The ComPtr
and ComRef
smart pointers manage this
automatically where possible, but the function signatures generated by com-scrape
still pass
COM objects as raw pointers, and care must be taken to handle issues of ownership correctly
when converting between ComPtr
or ComRef
and raw pointers at these boundaries.
A thorough overview of how to manage reference counts for COM objects in a variety of situations
can be found on the "Rules for Managing Reference Counts" page in the Microsoft COM
documentation, and the documentation for each individual ComPtr
andComRef
method
specifies its effect on an object's reference count. However, the following rules of thumb
should suffice in the majority of situations:
-
When passing an interface pointer as a function parameter, use
ComPtr::as_ptr
to obtain a raw pointer from aComPtr
, or useComRef::as_ptr
to obtain a raw pointer from aComRef
. -
When receiving an interface pointer as the return value of a function (or via an out parameter), always use
ComPtr::from_raw
to obtain aComPtr
from the raw pointer. -
When receiving an interface pointer as a function parameter, always use
ComRef::from_raw
to obtain aComRef
from the raw pointer. If the received interface pointer will be stored beyond the duration of the current function, useComRef::to_com_ptr
to upgrade theComRef
to aComPtr
. -
When returning an interface pointer from a function (or when returning it via an out parameter), always use
ComPtr::into_raw
to obtain a raw pointer from aComPtr
.
Implementing COM interfaces from Rust
The Class
trait can be used to define COM classes in Rust, and the ComWrapper
smart
pointer can be used to instantiate objects of these classes. To define a COM class, start by
defining a Rust type:
struct MyClass { /* ... */ }
Then implement the desired interface traits for the type:
impl ISomeInterfaceTrait for MyClass {
unsafe fn some_method(&self) {
/* ... */
}
}
impl IAnotherInterfaceTrait for MyClass {
unsafe fn another_method(&self) {
/* ... */
}
}
Finally, implement the Class
trait for the type, specifying the set of COM interfaces as a
tuple:
impl Class for MyClass {
type Interfaces = (ISomeInterface, IAnotherInterface);
}
With these definitions in place, ComWrapper
can be used to instantiate a COM object
supporting the above interfaces:
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();