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

Consume IDynamicInterfaceCastable in the .NET 5 projection #369

Merged
merged 26 commits into from
Sep 26, 2020

Conversation

jkoritzinsky
Copy link
Member

@jkoritzinsky jkoritzinsky commented Aug 14, 2020

Use IDynamicInterfaceCastable to drive the managed->native calls in the .NET 5 projection.

Stop shipping the .NET Standard 2.0 projection.

TODO:

  • Validate that interface that inherit from collection types correctly implement all of the interface members from direct and transitive parents.
  • Move manually written type mappings over to IDynamicInterfaceCastable for .NET 5.
  • Update the RCW creation (not activation) to instantiate WinRT.IInspectable for all interface types on .NET 5.

…as linked away since no members on the interface were called.
… hood via an internal IInspectable instance.
…nterfaces of runtime classes such that they can live in different projections and compile with only the public contract exposed.
@jkoritzinsky
Copy link
Member Author

There are a few perf losses in this PR that we should work on before merging this in:

  • Calls are slightly slower since they need to get the object reference from the cache instead of it just being a field on the object.
  • A cast that is not cached is significantly slower due to the reflection used to get a correctly typed vtable.

@Scottj1s Scottj1s changed the title WIP: Consume IDynamicInterfaceCastable in the .NET 5 projection Consume IDynamicInterfaceCastable in the .NET 5 projection Sep 23, 2020
@Scottj1s
Copy link
Member

  <group targetFramework=".NETStandard2.0" />

let's not remove just yet - there are non-Unity projects (WinML) that are evaluating cswinrt netstandard2.0


Refers to: nuget/Microsoft.Windows.CsWinRT.nuspec:17 in 471979e. [](commit_id = 471979e, deletion_comment = True)

auto type_name = write_type_name_temp(w, type, "%", true);
//std::cout << type_name << std::endl << std::endl << std::endl;
Copy link
Member

Choose a reason for hiding this comment

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

cruft

@jkoritzinsky
Copy link
Member Author

We should make sure to ship it in a separate package then. Otherwise people might get TypeLoadExceptions if they make a library targeting .NET Standard 2.0 and an application targeting .NET 5.0-Windows.

@Scottj1s
Copy link
Member

#include

cruft? (std::cout)


Refers to: cswinrt/code_writers.h:6 in 471979e. [](commit_id = 471979e, deletion_comment = False)


}

#if NETCOREAPP2_0
Copy link
Member

Choose a reason for hiding this comment

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

is the failing test? if so can you add a comment/TODO?

Copy link
Contributor

Choose a reason for hiding this comment

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

This is not, but this test uses the ABI type directly which is not possible with IDIC anymore so I removed it from .net5

@@ -775,7 +777,7 @@ public void TestClassGeneric()
{
var obj = objs[i];
Assert.Same(obj, TestObject);
Assert.Equal(TestObject.ThisPtr, objs[i].ThisPtr);
Assert.Equal(TestObject, objs[i]);
Copy link
Member

Choose a reason for hiding this comment

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

how come the ThisPtr check was removed?

Copy link
Member Author

Choose a reason for hiding this comment

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

There's no longer a ThisPtr property exposed because it makes the public surface area not match the WinMD contract and it isn't entirely accurate for composed types. There's no good reason to use the ThisPtr property, so I removed it early in the design.

@Scottj1s
Copy link
Member

using System;

I don't see any IDynamicInterfaceCastable tests - can we add a few?


Refers to: UnitTest/TestComponentCSharp_Tests.cs:1 in 471979e. [](commit_id = 471979e, deletion_comment = False)

@@ -16,7 +16,7 @@ public enum TrustLevel
// IInspectable
[ObjectReferenceWrapper(nameof(_obj))]
[Guid("AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90")]
public class IInspectable
public partial class IInspectable
Copy link
Member

Choose a reason for hiding this comment

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

partial only to combine with IInspectable.net5.cs? #if NET5_0 might be simpler

Copy link
Member Author

Choose a reason for hiding this comment

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

Given that IInspectable implements an extra interface in .NET 5.0, we'd have to add quite a few #if NET5_0 lines throughout the file. It's easier IMO to have two separate files.

public static readonly Vftbl AbiToProjectionVftable;
public static readonly IntPtr AbiToProjectionVftablePtr;

#if NETSTANDARD2_0
Copy link
Member

Choose a reason for hiding this comment

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

cruft: everywhere we've forked sources, we can get rid of conditional compilation

@Scottj1s
Copy link
Member

many of the .net5.cs/.netstandard2.0.cs splits seem unnecessary (the sources are identical). are we expecting them to diverge? if not, can we remove the duplication?

@Scottj1s
Copy link
Member

We should make sure to ship it in a separate package then. Otherwise people might get TypeLoadExceptions if they make a library targeting .NET Standard 2.0 and an application targeting .NET 5.0-Windows.

I'm fine with that for RTM - we have a few validation scenarios that are targeting netstandard2.0 that I want to keep enabled in the meantime.

Copy link
Member

@Scottj1s Scottj1s left a comment

Choose a reason for hiding this comment

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

:shipit:

public static readonly Vftbl AbiToProjectionVftable;
public static readonly IntPtr AbiToProjectionVftablePtr;

#if NETSTANDARD2_0
Copy link
Member

Choose a reason for hiding this comment

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

Do we need netstandard compat in a net5 file?

Copy link
Member

Choose a reason for hiding this comment

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

How much diff is there to merge both files?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think I fixed it in a newer commit.

}

public bool _MoveNext()
{
Copy link
Member

Choose a reason for hiding this comment

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

Is it possible for someone to call movenext first without calling current or hascurrent or is it just us calling it? If it is possible, would that make m_firstItem wrong?

}
catch (InvalidCastException elementCastException)
{
//global::System.Exception e = new InvalidCastException(string.Format(SR.InvalidCast_WinRTIPropertyValueArrayCoersion, value.GetType(), typeof(T[]).Name, i, elementCastException.Message), elementCastException.HResult);
Copy link
Member

Choose a reason for hiding this comment

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

is commented code intentional?

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.

4 participants