You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Progress on this crate has been fairly quite as we've been focusing on getting winrt-rs in working order. Now that that crate has solidified somewhat, it's time to return to this crate with the lessons learned from winrt. The following is a suggestion on the way we will proceed forward based on conversations I've had with @kennykerr. Please let us know if you have any feedback.
Traits vs Structs
Currently, COM interfaces are modeled as traits that must be used in conjunction with a ComPtr (for non-reference counting) or ComRc (for reference counting). This has certain advantages and disadvantages:
Pros
a familiar syntax for defining COM interfaces
built in support for ensuring that all methods are implemented for a given interface when building a COM server
Both Pro and Con
requires use of dyn keyword when dealing with interfaces. This is good in that it's a gentle reminder the user is performing dynamic dispatch, but it is extra syntax when presumably the user knows COM is dynamic dispatch.
Cons
extra syntax when taking a normal COM pointer as an argument: ComPtr<dyn IAnimal> vs IAnimal
strengths are for the less common case of producing COM interfaces rather than consuming
Not how COM works in other languages and thus might be slightly confusing to learn.
While switching to structs would not only be wins, there are enough here that it seems like the correct thing to do.
This would require a new syntax for defining COM interfaces. Something like the following:
Consumption of those interfaces would then look like this:
let factory = get_class_object(&CLSID_CAT_CLASS).unwrap();println!("Got cat class object");let unknown = factory
.query_interface::<IUnknown>().unwrap()println!("Got IUnknown");let animal = unknown
.query_interface::<IAnimal>().unwrap();println!("Got IAnimal");unsafe{ animal.eat()};
Nullability
Currently ComPtr is used only for non-null pointers.
Pros
no null checks required for the user when the user has a ComPtr meaning they can never make a mistake and use a ComPtr that has not actually been initialized. This is the very reason Option<T> exists in Rust.
Cons
null COM pointers are used in many common API patterns including out params. Currently this requires the user to first initialize a raw pointer, pass that pointer as the out param and then initialize the ComPtr struct with the raw pointer which can be awkward.
Currently there is a safe variant of query_interface that is called get_interface. The name difference is due to query_interface already existing and there being no method overloads. This is perhaps confusing, but the only two choices are to give the safe variant a different name (as is the case now), or give the unsafe variant a different name.
The text was updated successfully, but these errors were encountered:
Progress on this crate has been fairly quite as we've been focusing on getting winrt-rs in working order. Now that that crate has solidified somewhat, it's time to return to this crate with the lessons learned from winrt. The following is a suggestion on the way we will proceed forward based on conversations I've had with @kennykerr. Please let us know if you have any feedback.
Traits vs Structs
Currently, COM interfaces are modeled as traits that must be used in conjunction with a
ComPtr
(for non-reference counting) orComRc
(for reference counting). This has certain advantages and disadvantages:Pros
Both Pro and Con
dyn
keyword when dealing with interfaces. This is good in that it's a gentle reminder the user is performing dynamic dispatch, but it is extra syntax when presumably the user knows COM is dynamic dispatch.Cons
ComPtr<dyn IAnimal>
vsIAnimal
While switching to structs would not only be wins, there are enough here that it seems like the correct thing to do.
This would require a new syntax for defining COM interfaces. Something like the following:
and for implementing those interfaces:
Consumption of those interfaces would then look like this:
Nullability
Currently
ComPtr
is used only for non-null pointers.Pros
ComPtr
meaning they can never make a mistake and use aComPtr
that has not actually been initialized. This is the very reasonOption<T>
exists in Rust.Cons
ComPtr
struct with the raw pointer which can be awkward.This is being discussed already in #141
Method names
Currently there is a safe variant of
query_interface
that is calledget_interface
. The name difference is due toquery_interface
already existing and there being no method overloads. This is perhaps confusing, but the only two choices are to give the safe variant a different name (as is the case now), or give the unsafe variant a different name.The text was updated successfully, but these errors were encountered: