diff --git a/src/WinRT.Runtime/Marshalers.cs b/src/WinRT.Runtime/Marshalers.cs index a3d930bbe..7e32c68a1 100644 --- a/src/WinRT.Runtime/Marshalers.cs +++ b/src/WinRT.Runtime/Marshalers.cs @@ -1720,11 +1720,11 @@ internal static class Marshaler private static object ReturnParameter(object arg) => arg; - private static unsafe void CopyIntEnum(object value, IntPtr dest) => *(int*)dest.ToPointer() = (int)Convert.ChangeType(value, typeof(int)); + private static unsafe void CopyIntEnum(object value, IntPtr dest) => *(int*)dest.ToPointer() = Convert.ToInt32(value); private static unsafe void CopyIntEnumDirect(object value, IntPtr dest) => *(int*)dest.ToPointer() = (int)value; - private static unsafe void CopyUIntEnum(object value, IntPtr dest) => *(uint*)dest.ToPointer() = (uint)Convert.ChangeType(value, typeof(uint)); + private static unsafe void CopyUIntEnum(object value, IntPtr dest) => *(uint*)dest.ToPointer() = Convert.ToUInt32(value); private static unsafe void CopyUIntEnumDirect(object value, IntPtr dest) => *(uint*)dest.ToPointer() = (uint)value; } diff --git a/src/WinRT.Runtime/Projections/IPropertyValue.net5.cs b/src/WinRT.Runtime/Projections/IPropertyValue.net5.cs index 817ef7e2a..04ea9a9f4 100644 --- a/src/WinRT.Runtime/Projections/IPropertyValue.net5.cs +++ b/src/WinRT.Runtime/Projections/IPropertyValue.net5.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using WinRT; @@ -106,8 +107,8 @@ internal static class ManagedIPropertyValueImpl private const int TYPE_E_TYPEMISMATCH = unchecked((int)0x80028CA0); private const int DISP_E_OVERFLOW = unchecked((int)0x8002000A); private static IPropertyValue.Vftbl AbiToProjectionVftable; - public static IntPtr AbiToProjectionVftablePtr; - + public static IntPtr AbiToProjectionVftablePtr; + internal static readonly Guid IID = new(0x4BD682DD, 0x7554, 0x40E9, 0x9A, 0x9B, 0x82, 0x65, 0x4E, 0xDE, 0x7E, 0x62); static unsafe ManagedIPropertyValueImpl() @@ -325,12 +326,46 @@ private static T CoerceValue(object value) { return (T)(object)guid.ToString("D", global::System.Globalization.CultureInfo.InvariantCulture); } + else if (typeof(T) == typeof(byte)) + { + return (T)(object)Convert.ToByte(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(short)) + { + return (T)(object)Convert.ToInt16(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(ushort)) + { + return (T)(object)Convert.ToUInt16(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(int)) + { + return (T)(object)Convert.ToInt32(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(uint)) + { + return (T)(object)Convert.ToUInt32(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(long)) + { + return (T)(object)Convert.ToInt64(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(ulong)) + { + return (T)(object)Convert.ToUInt64(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(float)) + { + return (T)(object)Convert.ToSingle(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(double)) + { + return (T)(object)Convert.ToDouble(value, global::System.Globalization.CultureInfo.InvariantCulture); + } else { - if (NumericScalarTypes.TryGetValue(typeof(T), out _)) - { - return (T)Convert.ChangeType(value, typeof(T), global::System.Globalization.CultureInfo.InvariantCulture); - } + Debug.Assert(!NumericScalarTypes.ContainsKey(typeof(T))); + throw new InvalidCastException("", TYPE_E_TYPEMISMATCH); } } catch (FormatException) diff --git a/src/WinRT.Runtime/Projections/IPropertyValue.netstandard2.0.cs b/src/WinRT.Runtime/Projections/IPropertyValue.netstandard2.0.cs index 4e1b4ff08..5508d1304 100644 --- a/src/WinRT.Runtime/Projections/IPropertyValue.netstandard2.0.cs +++ b/src/WinRT.Runtime/Projections/IPropertyValue.netstandard2.0.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using WinRT; @@ -106,8 +107,8 @@ internal static class ManagedIPropertyValueImpl private const int TYPE_E_TYPEMISMATCH = unchecked((int)0x80028CA0); private const int DISP_E_OVERFLOW = unchecked((int)0x8002000A); private static IPropertyValue.Vftbl AbiToProjectionVftable; - public static IntPtr AbiToProjectionVftablePtr; - + public static IntPtr AbiToProjectionVftablePtr; + internal static readonly Guid IID = new(0x4BD682DD, 0x7554, 0x40E9, 0x9A, 0x9B, 0x82, 0x65, 0x4E, 0xDE, 0x7E, 0x62); private static readonly Delegate[] DelegateCache = new Delegate[39]; @@ -327,12 +328,46 @@ private static T CoerceValue(object value) { return (T)(object)guid.ToString("D", global::System.Globalization.CultureInfo.InvariantCulture); } + else if (typeof(T) == typeof(byte)) + { + return (T)(object)Convert.ToByte(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(short)) + { + return (T)(object)Convert.ToInt16(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(ushort)) + { + return (T)(object)Convert.ToUInt16(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(int)) + { + return (T)(object)Convert.ToInt32(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(uint)) + { + return (T)(object)Convert.ToUInt32(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(long)) + { + return (T)(object)Convert.ToInt64(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(ulong)) + { + return (T)(object)Convert.ToUInt64(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(float)) + { + return (T)(object)Convert.ToSingle(value, global::System.Globalization.CultureInfo.InvariantCulture); + } + else if (typeof(T) == typeof(double)) + { + return (T)(object)Convert.ToDouble(value, global::System.Globalization.CultureInfo.InvariantCulture); + } else { - if (NumericScalarTypes.TryGetValue(typeof(T), out _)) - { - return (T)Convert.ChangeType(value, typeof(T), global::System.Globalization.CultureInfo.InvariantCulture); - } + Debug.Assert(!NumericScalarTypes.ContainsKey(typeof(T))); + throw new InvalidCastException("", TYPE_E_TYPEMISMATCH); } } catch (FormatException)