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

Marshalling IEnumerable<T> in modern UWP fails #1839

Open
devsko opened this issue Oct 21, 2024 · 6 comments
Open

Marshalling IEnumerable<T> in modern UWP fails #1839

devsko opened this issue Oct 21, 2024 · 6 comments
Labels
bug Something isn't working

Comments

@devsko
Copy link

devsko commented Oct 21, 2024

Describe the bug
Calling WinRT with parameters of type IEnumerable<T> in modern UWP fails with various exceptions depending on T and parameter type.

To Reproduce

  1. Create a new .NET 9 UWP project
  2. Add <WindowsSDKPackageVersion>10.0.26100.54</WindowsSDKPackageVersion> and <AllowUnsafeBlocks>true</AllowUnsafeBlocks> to .csproj
  3. Add a Page_Loaded handler to MainPage with this code:
            new Geopath([new BasicGeoposition(0, 0, 0)]); // BasicGeoposition is a value type
            // System.InvalidCastException: Specified cast is not valid.
            //    at System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32 errorCode)
            //    at WinRT.ComWrappersSupport.CreateCCWForObjectForABI(Object obj, Guid iid)
            //    at WinRT.ComWrappersSupport.CreateCCWForObjectForMarshaling(Object obj, Guid iid)
            //    at WinRT.MarshalInspectable`1.CreateMarshaler2(T o, Guid iid, Boolean unwrapObject)
            //    at WinRT.MarshalInterface`1.CreateMarshaler2(T value, Guid iid)
            //    at Windows.Devices.Geolocation.Geopath._IGeopathFactoryMethods.Create(IObjectReference _obj, IEnumerable`1 positions)
            //    at Windows.Devices.Geolocation.Geopath..ctor(IEnumerable`1 positions)

            new Geopath(new BasicGeoposition[] { new(0, 0, 0) });
            // System.NotSupportedException: Cannot provide IReferenceArray`1 support for element type 'Windows.Devices.Geolocation.BasicGeoposition'.
            //    at WinRT.ComWrappersSupport.ProvideIReferenceArray(Type arrayType)
            //    at WinRT.ComWrappersSupport.GetInterfaceTableEntries(Type type)
            //    at WinRT.DefaultComWrappers.<>c.<ComputeVtables>b__7_0(Type type)
            //    at System.Runtime.CompilerServices.ConditionalWeakTable`2.GetValueLocked(TKey key, CreateValueCallback createValueCallback)
            //    at System.Runtime.CompilerServices.ConditionalWeakTable`2.GetValue(TKey key, CreateValueCallback createValueCallback)
            //    at WinRT.DefaultComWrappers.ComputeVtables(Object obj, CreateComInterfaceFlags flags, Int32& count)
            //    at System.Runtime.InteropServices.ComWrappers.TryGetOrCreateComInterfaceForObjectInternal(ObjectHandleOnStack comWrappersImpl, Int64 wrapperId, ObjectHandleOnStack instance, CreateComInterfaceFlags flags, IntPtr& retValue)
            //    at System.Runtime.InteropServices.ComWrappers.TryGetOrCreateComInterfaceForObjectInternal(ComWrappers impl, Object instance, CreateComInterfaceFlags flags, IntPtr& retValue)
            //    at System.Runtime.InteropServices.ComWrappers.GetOrCreateComInterfaceForObject(Object instance, CreateComInterfaceFlags flags)
            //    at WinRT.ComWrappersSupport.CreateCCWForObjectForABI(Object obj, Guid iid)
            //    at WinRT.ComWrappersSupport.CreateCCWForObjectForMarshaling(Object obj, Guid iid)
            //    at WinRT.MarshalInspectable`1.CreateMarshaler2(T o, Guid iid, Boolean unwrapObject)
            //    at WinRT.MarshalInterface`1.CreateMarshaler2(T value, Guid iid)
            //    at Windows.Devices.Geolocation.Geopath._IGeopathFactoryMethods.Create(IObjectReference _obj, IEnumerable`1 positions)
            //    at Windows.Devices.Geolocation.Geopath..ctor(IEnumerable`1 positions)

            MapStyleSheet.Combine([MapStyleSheet.Aerial()]); // MapStyleSheet is a reference type
            // System.InvalidCastException: Specified cast is not valid.
            //    at WinRT.ComWrappersSupport.CreateCCWForObjectForABI(Object obj, Guid iid)
            //    at WinRT.ComWrappersSupport.CreateCCWForObjectForMarshaling(Object obj, Guid iid)
            //    at WinRT.MarshalInspectable`1.CreateMarshaler2(T o, Guid iid, Boolean unwrapObject)
            //    at System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32 errorCode)
            //    at WinRT.MarshalInterface`1.CreateMarshaler2(T value, Guid iid)
            //    at ABI.Windows.UI.Xaml.Controls.Maps.IMapStyleSheetStaticsMethods.Combine(IObjectReference _obj, IEnumerable`1 styleSheets)
            //    at Windows.UI.Xaml.Controls.Maps.MapStyleSheet.Combine(IEnumerable`1 styleSheets)

            MapStyleSheet.Combine(new MapStyleSheet[] { MapStyleSheet.Aerial() }); 
            // works when AllowUnsafeBlocks=true, InvalidCastException otherwise

Expected behavior

No exceptions

Version Info

net9.0 rc2, Windows SDK 26100

Additional context

Creating a Geopath in WinUI3 works as expected. (MapStyleSheet is not available in WinUI3)

@devsko devsko added the bug Something isn't working label Oct 21, 2024
@dongle-the-gadget
Copy link
Contributor

CsWinRT does not yet support collection expressions in AOT mode. As for the reference type array, it works with unsafe code because CsWinRT needs that to generate AOT shims.

The value-type-array error does look to be an oversight though. cc @manodasanW

@manodasanW
Copy link
Member

manodasanW commented Oct 22, 2024

We didn't initially support boxing arrays using IReferenceArray due to we couldn't make it work with non-blittable scenarios on AOT. But I am working on a change to enable it for blittable scenarios such as this one.

In the meantime, you should be able to use a list rather than an array or collection expression and it should work.

@devsko
Copy link
Author

devsko commented Oct 22, 2024

I tried new Geopath(new List<BasicGeoposition>() { new(0, 0, 0) }); which gives the exact same exception as the one with collection expression.
On WinUI3 all of them work perfectly.

@manodasanW
Copy link
Member

Can you confirm the version of the .NET 9 SDK you are using? And to confirm, do you have AllowUnsafeBlocks enabled?

@devsko
Copy link
Author

devsko commented Oct 22, 2024

It is 9.0.100-rc.2.24474.11
I uploaded the repro https://github.com/devsko/App10

@Gaoyifei1011
Copy link
Contributor

Image

#1846

Are the internal anomalous causes of the two issues consistent?

-------------------------------------

这俩个问题的内部异常原因是一致的吗?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants