-
Notifications
You must be signed in to change notification settings - Fork 263
Extend weak reference support to classic COM #1104
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
Conversation
Right now, if you call `get_weak()` from a class that does not support weak references, you get the message > This is only for weak ref support. This message appears to be some sort of internal error and creates developer confusion. Updated the error so that you get > Weak references are not supported by this class. and one (or both) of * Weak references are not supported because object does not implement IInspectable. * Weak references are not supported because no_weak_ref was specified.
get_weak() is not supported
|
Thanks I'll take a look soon. I just wanted to point out that weak references don't actually require IInspectable. That's something I came to realize after implementing this in cppwinrt. So if it simplifies things we could simply remove that constraint. |
|
Yeah, it's weird because |
|
I spoke to the author of the header, and it sounds like it was just an honest mistake (which will confuse C++ developers forever). Either way, both caller and callee must agree on the interface being requested and in practice this is implemented using |
|
The parameter is annotated as |
|
If IInspectable is not needed, is it too late to fix the header? |
|
Confirmed that COM does not pay attention to the return type Bonus confirmed that the proxy data is identical to the version where the second parameter is annotated as |
Fixing the SDK has huge compat implications, so we generally don't do that. Besides, most projects should be using a language projection which would hide such details. |
Turns out that IWeakReference does work for classic COM: Even though the output pointer of `IWeakReference::Resolve` is typed as `IInspectable**`, it is annotated as `iid_is(riid)`, so COM ignores the formal type and relies on the IID, which is not constrained to derive from IInspectable. Verified that the COM marshaling metadata for the Resolve method is unaffected by the formal type of the output pointer. In particular, querying the resulting object for `IInspectable` will send a request over the wire (if never requested before), proving the COM did not infer `IInspectable` support. This is a behavior change: Previously, pure classic COM objects did not support weak references. However, it removes developer surprise, since they see a method called `get_weak()` and expect it to work.
get_weak() is not supported
kennykerr
left a comment
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.
Thanks!
Turns out that
IWeakReferencedoes work for classic COM: Even though the output pointer ofIWeakReference::Resolveis typed asIInspectable**, it is annotated asiid_is(riid), so COM ignores the formal type and relies on the IID, which is not constrained to derive from IInspectable. Verified that the COM marshaling metadata for the Resolve method is unaffected by the formal type of the output pointer. In particular, querying the resulting object forIInspectablewill send a request over the wire (if never requested before), proving the COM did not inferIInspectablesupport.This is a behavior change: Previously, pure classic COM objects did not support weak references. However, it removes developer surprise, since they see a method called
get_weak()and expect it to work.Also improved the diagnostic in the case where you call
get_weak()from a class that does not support weak references. The old error message wasThis message appears to be some sort of internal error and creates developer confusion.
Updated the error so that you get
Used
if constexprinmake_weak_refto generate the assertion only once per violation. The previous code generated the assertion but tried to compile the code anyway, resulting in confusing cascade errors which obscured the root cause.