-
Notifications
You must be signed in to change notification settings - Fork 493
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
COM interface impls move from MyApp to MyApp_Impl ("outer" object) #3065
COM interface impls move from MyApp to MyApp_Impl ("outer" object) #3065
Conversation
508bd93
to
ccf95f8
Compare
More fundamentally, the problem with the existing implementation is that certain functions - like casting/querying for an interface implemented by the implementation - assume that the type that the
#[implement(IFoo)]
struct MyApp { ... }
impl IFoo_Impl for MyApp_Impl { ... } There's no hint that |
The more I think about it, I think we should just flip to Edit: Actually, I just thought of something. What about this? impl IFoo_Impl for ComObject<MyApp> {
...
} This actually compiles. I haven't tried wiring up the method dispatch code to it, but this might be a good approach. |
Ok, I implemented support for placing interface impls on I created a draft PR, #3071 , just for discussion. That PR still has the "inner vs. outer" option on |
I like this!
|
Me too! ... Unfortunately, I tried taking that all the way to completion, and ran into an unsolvable problem with generics and trait implementations. It's not going to work. :( |
021fd1e
to
bc86afc
Compare
self.current | ||
.fetch_add(1, std::sync::atomic::Ordering::Relaxed); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this just formatting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. These files weren't being run through rustfmt before.
use windows_core::IUnknownImpl; | ||
Ok(windows_core::ComObject::new(StockIterator { | ||
owner: self.to_object(), | ||
current: 0.into(), | ||
}) | ||
.into_interface()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder, can we implement Into
/From
here as a shorthand for the simple case of returning the interface as before - then it would be similar to before: Ok(StockIterator {...}.into())
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The into()
thing still totally works. I just like the ComObject::new(...).into_interface()
more because it's more explicit.
where | ||
T: windows_core::RuntimeType, | ||
T::Default: Clone, | ||
{ | ||
fn Current(&self) -> windows_core::Result<T> { | ||
let owner: &StockIterable<T> = unsafe { windows_core::AsImpl::as_impl(&self.owner) }; | ||
let owner: &StockIterable<T> = &self.owner; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much nicer.
@@ -85,6 +88,6 @@ where | |||
type Error = windows_core::Error; | |||
fn try_from(values: Vec<T::Default>) -> windows_core::Result<Self> { | |||
// TODO: should provide a fallible try_into or more explicit allocator | |||
Ok(StockIterable { values }.into()) | |||
Ok(windows_core::ComObject::new(StockIterable { values }).into_interface()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above, be nice if this simple case had a shorthand.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It still works; just being explicit. I can change this back, but I like the explicitness.
Looks like a new Rust nightly update is failing the merge build workflow. #3096 |
This PR requires COM objects to implement COM interfaces on the "outer" (
MyApp_Impl
) type, which is generated by the#[implement]
macro, instead of the user-defined (or "inner") (MyApp
) type. This is important because many COM objects need access to the full COM object, not just the contents of the wrapped "inner" type.For example, COM objects may need to cast themselves to a particular
IFoo
that they implement and then return thatIFoo
pointer as an output parameter of a COM method call. This is not possible in the current design because COM objects receive method calls that are typed&self : T
whereT
is the inner type, so they do not have access to the vtables or reference count of the current COM object.This is a breaking change to all code that uses the
#[implement]
macro. All code in this pattern:will need to be changed to this: