Skip to content

Conversation

Sergio0694
Copy link
Member

@Sergio0694 Sergio0694 commented Oct 10, 2025

This PR includes a few changes to 'WinRT.Runtime.dll':

  • Update WindowsRuntimeValueTypeMarshaller to take explicit flags.
  • Add WindowsRuntimeComWrappersMarshal to avoid double boxing for value types
  • Centralized the "private implementation detail" message
  • Annotated all actual private implementation detail types, and moved some APIs to separate types for better separation
  • Add WindowsRuntimeMarshal.NativeReferenceEqual

Updated all marshaller classes to pass CreateComInterfaceFlags.None explicitly to BoxToUnmanaged. Refactored WindowsRuntimeValueTypeMarshaller to require flags as a parameter and added an overload for boxed objects. This improves clarity and flexibility in COM interface creation for value types.
Introduces WindowsRuntimeConstants class containing an internal message for private implementation detail types, clarifying their intended usage and versioning policy.
Replaces hardcoded Obsolete attribute messages with WindowsRuntimeConstants.PrivateImplementationDetailObsoleteMessage for internal implementation detail types. This change improves maintainability and consistency of obsolete messaging across WindowsRuntime collection, interop, and event source classes.
Added [Obsolete] and [EditorBrowsable(EditorBrowsableState.Never)] attributes to internal implementation classes in ProjectionImpls and TypeMapGroups to discourage direct usage and hide them from IntelliSense. This clarifies their intended use as private implementation details.
Added [Obsolete] attributes to internal constructors, properties, and methods in WindowsRuntimeObject to indicate they are for private implementation details and should not be used. This helps guide developers away from using these APIs directly.
Added [Obsolete] attributes with a private implementation detail message to marshaller types and related internal APIs. This clarifies that these types are intended only for generated projections and interop code, and are not supported for direct use in user code.
Moved COM marshalling methods from WindowsRuntimeMarshal to a new WindowsRuntimeComWrappersMarshaller utility class. Updated all usages to reference the new class. Added [Obsolete] and [EditorBrowsable(EditorBrowsableState.Never)] attributes to internal APIs and related attributes to discourage external usage. This improves code organization and clarifies intended usage of marshalling helpers.
Introduces NativeReferenceEquals to check if two objects are the same or wrap the same underlying native COM object by comparing their IUnknown interface pointers. This helps ensure accurate identity checks for wrapped native objects.
Replaces calls to WindowsRuntimeComWrappers.Default.GetOrCreateComInterfaceForObject with WindowsRuntimeComWrappersMarshaller.GetOrCreateComInterfaceForObject across multiple ABI marshaller classes for consistency and maintainability.
Renamed WindowsRuntimeComWrappersMarshaller to WindowsRuntimeComWrappersMarshal throughout the codebase for consistency and clarity. Updated all references and usages in ABI and InteropServices files to use the new name.
Updated method calls in %ComWrappersMarshallerAttribute and %ComWrappersCallback classes to use WindowsRuntimeComWrappersMarshal instead of WindowsRuntimeMarshal for object reference and COM interface creation. This change ensures correct usage of the newer marshal API for Windows Runtime COM wrappers.
Applied [Obsolete] and [EditorBrowsable(EditorBrowsableState.Never)] attributes to IsOverridableInterface and HasUnwrappableNativeObjectReference overrides to discourage their use and hide them from IntelliSense.
Replaces static ref readonly Guid IID properties with getter methods using MethodImplOptions.AggressiveInlining across multiple ABI classes. This change improves consistency and allows for future extensibility in how IIDs are resolved.
Replaced direct IID assignments with references to WellKnownInterfaceIds for AsyncActionCompletedHandler and IReferenceOfAsyncActionCompletedHandler. This improves consistency and centralizes interface ID management.
Added 'using System.ComponentModel;' to support types or attributes from the System.ComponentModel namespace in generated code.
@Sergio0694 Sergio0694 force-pushed the user/sergiopedri/optimize-boxing branch from faffe59 to 5eda476 Compare October 10, 2025 21:08
Changed BoxToUnmanaged and GetOrCreateComInterfaceForObject to use CreateObjectFlags.TrackerObject instead of default. Added TODO comments to consider using CreateObjectFlags.None when possible.
@Sergio0694 Sergio0694 force-pushed the user/sergiopedri/optimize-boxing branch from 205e799 to a1b50b0 Compare October 11, 2025 20:05
Updated references from CreateObjectFlags to CreateComInterfaceFlags in code generation templates and comments to reflect API changes. This ensures correct flag usage for COM interface creation and improves code consistency.
Replaces usage of WindowsRuntimeMarshal with WindowsRuntimeComWrappersMarshal in interop type builders and reference definitions. This change updates method and type references to align with the new marshal class, improving consistency and future compatibility.
bool has_base_class = !std::holds_alternative<object_type>(get_type_semantics(type.Extends()));
separator s{ w, " || " };
w.write(R"(
[Obsolete]
Copy link
Member

Choose a reason for hiding this comment

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

Is this going to show up as warnings when folks are generating projections.

Copy link
Member Author

Choose a reason for hiding this comment

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

It might show up as a warning if we ever use these directly from projections, but don't think we do? If we do, we can just add a #pragma warning disable CS0614 for that warning in the generated projection file I guess? 🤔

R"(public static WindowsRuntimeObjectReferenceValue BoxToUnmanaged(%? value)
{
return WindowsRuntimeValueTypeMarshaller.BoxToUnmanaged(value, in %ReferenceImpl.IID);
return WindowsRuntimeValueTypeMarshaller.BoxToUnmanaged(value, CreateComInterfaceFlags.TrackerSupport, in %ReferenceImpl.IID);
Copy link
Member

Choose a reason for hiding this comment

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

At a minimum. the TODO addressing this should make sure if it is blittable, pass none. And maybe strings are the only new scenarios that can also pass none?

Copy link
Member Author

Choose a reason for hiding this comment

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

We should always pass None except any field(s) are IReference<T> at any nesting depth.

/// <summary>
/// Marshaller for <see cref="global::System.ComponentModel.DataErrorsChangedEventArgs"/>.
/// </summary>
[Obsolete(WindowsRuntimeConstants.PrivateImplementationDetailObsoleteMessage)]
Copy link
Member

Choose a reason for hiding this comment

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

Generated projections would call this right? Not sure if we want to just keep EditorBrowsable rather than also obsolete.

Copy link
Member Author

Choose a reason for hiding this comment

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

I want the obsolete with the message to enforce that these are private implementation details. Generated projections can just suppress the warning and we can say it's allowed only for them to consume these assuming the WinRT version is exactly in sync (which we also require). But I'm also not entirely sure projections call these directly either.

/// Marshaller for <see cref="INotifyDataErrorInfo"/>.
/// </summary>
[Obsolete(WindowsRuntimeConstants.PrivateImplementationDetailObsoleteMessage)]
[EditorBrowsable(EditorBrowsableState.Never)]
Copy link
Member

Choose a reason for hiding this comment

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

same here and for methods and throughout other files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants