Skip to content
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

Add support for GeneratedComClassAttribute on WinRT classes #1858

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

dongle-the-gadget
Copy link
Contributor

@dongle-the-gadget dongle-the-gadget commented Oct 31, 2024

Fixes #1722.
Fixes #1851.

This PR includes two changes:

  • Modifying the default COM wrappers so that the vtables generated by the COM Wrappers generators are included.
  • Changing how WinRT interfaces are determined in the authoring generator. To be more specific, internal interfaces are now required to include WindowsRuntimeTypeAttribute to be considered a WinRT type, rather than all internal interfaces (which is the current behavior)

Copy link
Member

@Sergio0694 Sergio0694 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is one problem with this approach. The generated stubs will use:

try
{
    // Code...
}
catch (global::System.Exception __exception)
{
    ExceptionAsHResultMarshaller<int>.ConvertToUnmanaged(__exception);
}

But that will lose stacktrace info. We need:

try
{
    // Code...
}
catch (global::System.Exception __exception)
{
    ExceptionHelpers.SetErrorInfo(__exception);

    return ExceptionHelpers.GetHRForException(__exception);
}

Is there a way for users to annotate either the interface, or methods, or something, so the generated code can use the appropriate marshaller for this? We likely also need to actually implement this marshaller in WinRT.Runtime, so people can actually use it.

Without support for this, I feel like this isn't really usable yet.

cc. @manodasanW thoughts?

@Sergio0694
Copy link
Member

Something like this?

[CustomMarshaller(typeof(Exception), MarshalMode.UnmanagedToManagedOut, typeof(ExceptionHelpersHResultMarshaller<>))]
public static class ExceptionHelpersHResultMarshaller<T>
    where T : unmanaged, INumber<T>
{
    public static T ConvertToUnmanaged(Exception e)
    {
        ExceptionHelpers.SetErrorInfo(e);

        return T.CreateTruncating(ExceptionHelpers.GetHRForException(e));
    }
}

And then you should be able to use it like this maybe? idk:

[Guid("6234C2F7-9917-469F-BDB4-3E8C630598AF")]
[GeneratedComInterface(Options = ComInterfaceOptions.ManagedObjectWrapper)]
public partial interface IFoo
{
    [return: MarshalUsing(typeof(ExceptionHelpersHResultMarshaller<int>))]
    void Bar();
}

@manodasanW
Copy link
Member

Added Jeremy for his thoughts on this.

Copy link
Member

@jkoritzinsky jkoritzinsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this looks great and I love the integration with the modern source-generated COM experiences!

Sergio's comments about the exception experience are warranted. I think there should be a manual validation pass that the COM-style interfaces on WinRT types are using COM-style error handling, not WinRT-style handling, just to make sure there's a decent experience there.

@Sergio0694
Copy link
Member

"just to make sure there's a decent experience there"

What makes me a bit sad is that until we support this, eg. I won't be able to migrate interfaces like this to this 🥲

I'll go open an API proposal in the runtime repo for tracking.

@dongle-the-gadget
Copy link
Contributor Author

dongle-the-gadget commented Nov 5, 2024

Do we know whether these COM exceptions should be propagated through IErrorInfo or IRestrictedErrorInfo? If it's the former then it can be resolved through a .NET runtime update alone (as it is a COM interface, not WinRT).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants