From 58858cda5787f1d60c9657018899b0020545714f Mon Sep 17 00:00:00 2001 From: Jonathan Pobst Date: Wed, 29 Jan 2025 09:54:27 -1000 Subject: [PATCH 1/3] =?UTF-8?q?=EF=BB=BFTest=20JI=201296.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- external/Java.Interop | 2 +- .../Android.Runtime/ExtraDelegates.cs | 30 +++++++++++++++++++ src/Mono.Android/Mono.Android.csproj | 1 + .../Utilities/MarshalMethodsClassifier.cs | 27 +++++++++++++++-- 4 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 src/Mono.Android/Android.Runtime/ExtraDelegates.cs diff --git a/external/Java.Interop b/external/Java.Interop index 6bc87e8b55b..1efa6feca60 160000 --- a/external/Java.Interop +++ b/external/Java.Interop @@ -1 +1 @@ -Subproject commit 6bc87e8b55bc00ae1423a5ae92cf5db573fc76ed +Subproject commit 1efa6feca601d801fce43e120bf09f84714074ab diff --git a/src/Mono.Android/Android.Runtime/ExtraDelegates.cs b/src/Mono.Android/Android.Runtime/ExtraDelegates.cs new file mode 100644 index 00000000000..26101d9a2ea --- /dev/null +++ b/src/Mono.Android/Android.Runtime/ExtraDelegates.cs @@ -0,0 +1,30 @@ +// There are built-in delegates for these, but we no longer generate them in Mono.Android.dll +// because bool is not a blittable type. But we still need them for pre-existing bindings. +using System; + +[global::System.Runtime.InteropServices.UnmanagedFunctionPointer (global::System.Runtime.InteropServices.CallingConvention.Winapi)] +delegate bool _JniMarshal_PP_Z (IntPtr jnienv, IntPtr klass); +[global::System.Runtime.InteropServices.UnmanagedFunctionPointer (global::System.Runtime.InteropServices.CallingConvention.Winapi)] +delegate bool _JniMarshal_PPL_Z (IntPtr jnienv, IntPtr klass, IntPtr p0); +[global::System.Runtime.InteropServices.UnmanagedFunctionPointer (global::System.Runtime.InteropServices.CallingConvention.Winapi)] +delegate bool _JniMarshal_PPJ_Z (IntPtr jnienv, IntPtr klass, long p0); +[global::System.Runtime.InteropServices.UnmanagedFunctionPointer (global::System.Runtime.InteropServices.CallingConvention.Winapi)] +delegate void _JniMarshal_PPLZ_V (IntPtr jnienv, IntPtr klass, IntPtr p0, bool p1); +[global::System.Runtime.InteropServices.UnmanagedFunctionPointer (global::System.Runtime.InteropServices.CallingConvention.Winapi)] +delegate bool _JniMarshal_PPLL_Z (IntPtr jnienv, IntPtr klass, IntPtr p0, IntPtr p1); +[global::System.Runtime.InteropServices.UnmanagedFunctionPointer (global::System.Runtime.InteropServices.CallingConvention.Winapi)] +delegate bool _JniMarshal_PPIL_Z (IntPtr jnienv, IntPtr klass, int p0, IntPtr p1); +[global::System.Runtime.InteropServices.UnmanagedFunctionPointer (global::System.Runtime.InteropServices.CallingConvention.Winapi)] +delegate bool _JniMarshal_PPLII_Z (IntPtr jnienv, IntPtr klass, IntPtr p0, int p1, int p2); +[global::System.Runtime.InteropServices.UnmanagedFunctionPointer (global::System.Runtime.InteropServices.CallingConvention.Winapi)] +delegate bool _JniMarshal_PPLLJ_Z (IntPtr jnienv, IntPtr klass, IntPtr p0, IntPtr p1, long p2); +[global::System.Runtime.InteropServices.UnmanagedFunctionPointer (global::System.Runtime.InteropServices.CallingConvention.Winapi)] +delegate bool _JniMarshal_PPLIL_Z (IntPtr jnienv, IntPtr klass, IntPtr p0, int p1, IntPtr p2); +[global::System.Runtime.InteropServices.UnmanagedFunctionPointer (global::System.Runtime.InteropServices.CallingConvention.Winapi)] +delegate bool _JniMarshal_PPLLL_Z (IntPtr jnienv, IntPtr klass, IntPtr p0, IntPtr p1, IntPtr p2); +[global::System.Runtime.InteropServices.UnmanagedFunctionPointer (global::System.Runtime.InteropServices.CallingConvention.Winapi)] +delegate IntPtr _JniMarshal_PPIZI_L (IntPtr jnienv, IntPtr klass, int p0, bool p1, int p2); +[global::System.Runtime.InteropServices.UnmanagedFunctionPointer (global::System.Runtime.InteropServices.CallingConvention.Winapi)] +delegate bool _JniMarshal_PPLZZL_Z (IntPtr jnienv, IntPtr klass, IntPtr p0, bool p1, bool p2, IntPtr p3); +[global::System.Runtime.InteropServices.UnmanagedFunctionPointer (global::System.Runtime.InteropServices.CallingConvention.Winapi)] +delegate void _JniMarshal_PPZIIII_V (IntPtr jnienv, IntPtr klass, bool p0, int p1, int p2, int p3, int p4); diff --git a/src/Mono.Android/Mono.Android.csproj b/src/Mono.Android/Mono.Android.csproj index 093a6d6a8ac..6c409057f53 100644 --- a/src/Mono.Android/Mono.Android.csproj +++ b/src/Mono.Android/Mono.Android.csproj @@ -96,6 +96,7 @@ + diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/MarshalMethodsClassifier.cs b/src/Xamarin.Android.Build.Tasks/Utilities/MarshalMethodsClassifier.cs index 1507084dfc0..0dda2658d72 100644 --- a/src/Xamarin.Android.Build.Tasks/Utilities/MarshalMethodsClassifier.cs +++ b/src/Xamarin.Android.Build.Tasks/Utilities/MarshalMethodsClassifier.cs @@ -208,7 +208,7 @@ public bool Matches (MethodDefinition method) return false; } - if (String.Compare (returnType, method.ReturnType.FullName, StringComparison.Ordinal) != 0) { + if (!TypeMatches (returnType, method.ReturnType.FullName)) { log.LogWarning ($"Method '{method.FullName}' doesn't match native callback signature (invalid return type: expected '{returnType}', found '{method.ReturnType.FullName}')"); return false; } @@ -223,7 +223,7 @@ public bool Matches (MethodDefinition method) parameterTypeName = pd.ParameterType.FullName; } - if (String.Compare (parameterTypeName, paramTypes[i], StringComparison.Ordinal) != 0) { + if (!TypeMatches (parameterTypeName, paramTypes[i])) { log.LogWarning ($"Method '{method.FullName}' doesn't match native callback signature, expected parameter type '{paramTypes[i]}' at position {i}, found '{parameterTypeName}'"); return false; } @@ -231,6 +231,29 @@ public bool Matches (MethodDefinition method) return true; } + + // Because these types are marshaled as different blittable types, + // we need to accept them as equivalent + static readonly Tuple[] equivalent_types = new [] { + Tuple.Create ("System.Boolean", "System.SByte"), + Tuple.Create ("System.Char", "System.UInt16"), + }; + + static bool TypeMatches (string type, string methodType) + { + if (String.Compare (type, methodType, StringComparison.Ordinal) == 0) + return true; + + foreach (var eq in equivalent_types) { + if (string.Compare (eq.Item1, type, StringComparison.Ordinal) == 0 && string.Compare (eq.Item2, methodType, StringComparison.Ordinal) == 0) + return true; + + if (string.Compare (eq.Item1, methodType, StringComparison.Ordinal) == 0 && string.Compare (eq.Item2, type, StringComparison.Ordinal) == 0) + return true; + } + + return false; + } } TypeDefinitionCache tdCache; From 12955f70d17fd3f9e0319dcf986c9863f9ac3b18 Mon Sep 17 00:00:00 2001 From: Jonathan Pobst Date: Mon, 10 Feb 2025 11:40:58 -1000 Subject: [PATCH 2/3] Address review feedback. --- .../Utilities/MarshalMethodsClassifier.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/MarshalMethodsClassifier.cs b/src/Xamarin.Android.Build.Tasks/Utilities/MarshalMethodsClassifier.cs index 0dda2658d72..211baaf0948 100644 --- a/src/Xamarin.Android.Build.Tasks/Utilities/MarshalMethodsClassifier.cs +++ b/src/Xamarin.Android.Build.Tasks/Utilities/MarshalMethodsClassifier.cs @@ -234,10 +234,10 @@ public bool Matches (MethodDefinition method) // Because these types are marshaled as different blittable types, // we need to accept them as equivalent - static readonly Tuple[] equivalent_types = new [] { - Tuple.Create ("System.Boolean", "System.SByte"), - Tuple.Create ("System.Char", "System.UInt16"), - }; + static readonly (string Source, string Replacement)[] equivalent_types = [ + (Source: "System.Boolean", Replacement: "System.SByte"), + (Source: "System.Char", Replacement: "System.UInt16"), + ]; static bool TypeMatches (string type, string methodType) { @@ -245,10 +245,10 @@ static bool TypeMatches (string type, string methodType) return true; foreach (var eq in equivalent_types) { - if (string.Compare (eq.Item1, type, StringComparison.Ordinal) == 0 && string.Compare (eq.Item2, methodType, StringComparison.Ordinal) == 0) + if (string.Compare (eq.Source, type, StringComparison.Ordinal) == 0 && string.Compare (eq.Replacement, methodType, StringComparison.Ordinal) == 0) return true; - if (string.Compare (eq.Item1, methodType, StringComparison.Ordinal) == 0 && string.Compare (eq.Item2, type, StringComparison.Ordinal) == 0) + if (string.Compare (eq.Source, methodType, StringComparison.Ordinal) == 0 && string.Compare (eq.Replacement, type, StringComparison.Ordinal) == 0) return true; } From a95a284e3f8e2b79fd7355c6dcd8b65798401b44 Mon Sep 17 00:00:00 2001 From: Jonathan Pobst Date: Tue, 11 Feb 2025 10:52:55 -1000 Subject: [PATCH 3/3] Update JI. --- external/Java.Interop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/Java.Interop b/external/Java.Interop index 1efa6feca60..57f7bc849f3 160000 --- a/external/Java.Interop +++ b/external/Java.Interop @@ -1 +1 @@ -Subproject commit 1efa6feca601d801fce43e120bf09f84714074ab +Subproject commit 57f7bc849f36ec7c3159cc7729c7276b8dcd3ca4