diff --git a/external/Java.Interop b/external/Java.Interop index 6bc87e8b55b..57f7bc849f3 160000 --- a/external/Java.Interop +++ b/external/Java.Interop @@ -1 +1 @@ -Subproject commit 6bc87e8b55bc00ae1423a5ae92cf5db573fc76ed +Subproject commit 57f7bc849f36ec7c3159cc7729c7276b8dcd3ca4 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..211baaf0948 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 (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) + { + if (String.Compare (type, methodType, StringComparison.Ordinal) == 0) + return true; + + foreach (var eq in equivalent_types) { + if (string.Compare (eq.Source, type, StringComparison.Ordinal) == 0 && string.Compare (eq.Replacement, methodType, StringComparison.Ordinal) == 0) + return true; + + if (string.Compare (eq.Source, methodType, StringComparison.Ordinal) == 0 && string.Compare (eq.Replacement, type, StringComparison.Ordinal) == 0) + return true; + } + + return false; + } } TypeDefinitionCache tdCache;