-
Notifications
You must be signed in to change notification settings - Fork 124
Description
Description
Hello, I'm working on upgrading CsWinRT to 2.2.0 for SkiaSharp and I ran into this problem.
The idl file looks like this:
namespace SkiaSharp.Views.WinUI.Native
{
static runtimeclass BufferExtensions
{
static Int64 GetByteBuffer(Windows.Storage.Streams.IBuffer buffer);
}
}
CsWinRT 2.2.0 generates a corresponding method in the projection file:
internal static unsafe long GetByteBuffer(IObjectReference _obj, global::Windows.Storage.Streams.IBuffer buffer)
{
var ThisPtr = _obj.ThisPtr;
ObjectReferenceValue __buffer = default;
long __retval = default;
try
{
__buffer = MarshalInterface<global::Windows.Storage.Streams.IBuffer>.CreateMarshaler2(buffer, global::ABI.Windows.Storage.Streams.IBufferMethods.IID);
global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]<IntPtr, IntPtr, long*, int>**)ThisPtr)[6](ThisPtr, MarshalInspectable<object>.GetAbi(__buffer), &__retval));
global::System.GC.KeepAlive(_obj);
return __retval;
}
finally
{
MarshalInspectable<object>.DisposeMarshaler(__buffer);
}
}
It fails to build because global::ABI.Windows.Storage.Streams.IBufferMethods doesn't contain a definition for IID.
I checked the file generated by CsWinRT 2.0.4 and found out that the main difference is
__buffer = MarshalInterface<global::Windows.Storage.Streams.IBuffer>.CreateMarshaler2(buffer);
The optional IID parameter is not passed.
Steps To Reproduce
I uses this command to generate projection files.
.\cswinrt.exe -input D:\\GitHub\\SkiaSharp\\native\\winui\\SkiaSharp.Views.WinUI.Native\\SkiaSharp.Views.WinUI.Native\\bin\\x64\\Release\\SkiaSharp.Views.WinUI.Native.winmd -input "E:\\Windows Kits\\10\\UnionMetadata\\10.0.19041.0" -include SkiaSharp
The winmd file is here:
SkiaSharp.Views.WinUI.Native.winmd.zip
Then you will see this line in the generated SkiaSharp.Views.WinUI.Native.cs
__buffer = MarshalInterface<global::Windows.Storage.Streams.IBuffer>.CreateMarshaler2(buffer, global::ABI.Windows.Storage.Streams.IBufferMethods.IID);
Expected Behavior
SkiaSharp.Views.WinUI.Native.cs generated by CsWinRT 2.0.4 has this line:
__buffer = MarshalInterface<global::Windows.Storage.Streams.IBuffer>.CreateMarshaler2(buffer);
Instead of having an IID as second parameter, it directly ignore this optional parameter.
I'm not sure CsWinRT 2.0.4 is doing the correct thing, but at least the generated file doesn't make the build fail.
The reason I want to upgrade from 2.0.4 to 2.2.0 is that 2.0.4 is not trimming-safe. I'm not sure whether the purpose of adding this IID is making it trimming-safe or not.
Version Info
I'm using CsWinRT 2.2.0 from nuget package manager in Visual Studio 2022, the target framework of SkiaSharp is net6.
SkiaSharp targets Windows SDK 10.0.17763.0. But I reproduced this error when using 10.0.19041.0.
Additional Context
I made some effort and successfully built cswinrt.exe (still failed to build the whole solution but this is enough for me). I stepped into it and found this in set_abi_marshaler of version 2.2.0:
if (settings.netstandard_compat)
{
m.interface_guid = w.write_temp("GuidGenerator.GetIID(typeof(%).GetHelperType())", bind<write_type_name>(semantics, typedef_name_type::Projected, false));
}
else if (type.TypeNamespace() == "Windows.Foundation" && type.TypeName() == "IReference`1")
{
m.interface_guid = w.write_temp("%.PIID", bind<write_type_name>(semantics, typedef_name_type::ABI, false));
}
else
{
m.interface_guid = w.write_temp("%.IID", bind<write_type_name>(type, typedef_name_type::StaticAbiClass, true));
}
This code piece doesn't exist in version 2.0.4 so IID is not used as the second parameter.
I'm not familiar with how CsWinRT works. What does it mean? Why is it added when not adding it is also fine?