Skip to content

Commit 0b7f93b

Browse files
radekdoulikjonpryor
authored andcommitted
[jnimarshalmethod-gen] Do not miss registered methods (#357)
Fixes: #356 `Extensions.CheckMethod()` implicitly required that assemblies being processed contained debug symbols, because it used `ParameterDefinition.Name` in order to associate the `name` parameter of the `[Register]` custom attribute with the Java-side name. (`ParameterDefinition.Name` was via `registerAttribute.Constructor.Parameters`.) The problem is that if an assembly *doesn't* contain debug symbols, then `ParameterDefinition.Name` may be empty, meaning we may *skip over* methods with `[Register]` attributes. This in turn means that those methods won't be registered, which can result in a runtime crash. For example: I/mono-stdout( 2532): Registering JNI marshal methods in Xamarin.Forms.Platform.Android.CellAdapter W/art ( 2532): Attempt to remove index outside index area (6 vs 7-7) W/art ( 2532): JNI WARNING: DeleteLocalRef(0x1bf00019) failed to find entry The "traditional" Xamarin.Android Java Callable Wrapper describes 10 methods to register for this type: __md_methods = "n_onItemLongClick:(Landroid/widget/AdapterView;Landroid/view/View;IJ)Z:GetOnItemLongClick_Landroid_widget_AdapterView_Landroid_view_View_IJHandler:Android.Widget.AdapterView/IOnItemLongClickListenerInvoker, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null\n" + "n_onActionItemClicked:(Landroid/view/ActionMode;Landroid/view/MenuItem;)Z:GetOnActionItemClicked_Landroid_view_ActionMode_Landroid_view_MenuItem_Handler:Android.Views.ActionMode/ICallbackInvoker, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null\n" + "n_onCreateActionMode:(Landroid/view/ActionMode;Landroid/view/Menu;)Z:GetOnCreateActionMode_Landroid_view_ActionMode_Landroid_view_Menu_Handler:Android.Views.ActionMode/ICallbackInvoker, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null\n" + "n_onDestroyActionMode:(Landroid/view/ActionMode;)V:GetOnDestroyActionMode_Landroid_view_ActionMode_Handler:Android.Views.ActionMode/ICallbackInvoker, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null\n" + "n_onPrepareActionMode:(Landroid/view/ActionMode;Landroid/view/Menu;)Z:GetOnPrepareActionMode_Landroid_view_ActionMode_Landroid_view_Menu_Handler:Android.Views.ActionMode/ICallbackInvoker, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null\n" + "n_onItemClick:(Landroid/widget/AdapterView;Landroid/view/View;IJ)V:GetOnItemClick_Landroid_widget_AdapterView_Landroid_view_View_IJHandler:Android.Widget.AdapterView/IOnItemClickListenerInvoker, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null\n" + "n_onActionItemClicked:(Landroid/support/v7/view/ActionMode;Landroid/view/MenuItem;)Z:GetOnActionItemClicked_Landroid_support_v7_view_ActionMode_Landroid_view_MenuItem_Handler:Android.Support.V7.View.ActionMode/ICallbackInvoker, Xamarin.Android.Support.v7.AppCompat\n" + "n_onCreateActionMode:(Landroid/support/v7/view/ActionMode;Landroid/view/Menu;)Z:GetOnCreateActionMode_Landroid_support_v7_view_ActionMode_Landroid_view_Menu_Handler:Android.Support.V7.View.ActionMode/ICallbackInvoker, Xamarin.Android.Support.v7.AppCompat\n" + "n_onDestroyActionMode:(Landroid/support/v7/view/ActionMode;)V:GetOnDestroyActionMode_Landroid_support_v7_view_ActionMode_Handler:Android.Support.V7.View.ActionMode/ICallbackInvoker, Xamarin.Android.Support.v7.AppCompat\n" + "n_onPrepareActionMode:(Landroid/support/v7/view/ActionMode;Landroid/view/Menu;)Z:GetOnPrepareActionMode_Landroid_support_v7_view_ActionMode_Landroid_view_Menu_Handler:Android.Support.V7.View.ActionMode/ICallbackInvoker, Xamarin.Android.Support.v7.AppCompat\n" + ""; Meanwhile, `jnimarshalmethod-gen.exe` only finds and generates *6*: [JniAddNativeMethodRegistration] public static void __RegisterNativeMembers (JniNativeMethodRegistrationArguments args) { Console.WriteLine ("Registering JNI marshal methods in Xamarin.Forms.Platform.Android.CellAdapter"); args.AddRegistrations (new JniNativeMethodRegistration[6] { new JniNativeMethodRegistration ("n_onActionItemClicked", "(Landroid/view/ActionMode;Landroid/view/MenuItem;)Z", new Func<IntPtr, IntPtr, IntPtr, IntPtr, bool> (__<$>_jni_marshal_methods.n_onActionItemClicked_Landroid_view_ActionMode_Landroid_view_MenuItem_)), new JniNativeMethodRegistration ("n_onCreateActionMode", "(Landroid/view/ActionMode;Landroid/view/Menu;)Z", new Func<IntPtr, IntPtr, IntPtr, IntPtr, bool> (__<$>_jni_marshal_methods.n_onCreateActionMode_Landroid_view_ActionMode_Landroid_view_Menu_)), new JniNativeMethodRegistration ("n_onDestroyActionMode", "(Landroid/view/ActionMode;)V", new Action<IntPtr, IntPtr, IntPtr> (__<$>_jni_marshal_methods.n_onDestroyActionMode_Landroid_view_ActionMode_)), new JniNativeMethodRegistration ("n_onPrepareActionMode", "(Landroid/view/ActionMode;Landroid/view/Menu;)Z", new Func<IntPtr, IntPtr, IntPtr, IntPtr, bool> (__<$>_jni_marshal_methods.n_onPrepareActionMode_Landroid_view_ActionMode_Landroid_view_Menu_)), new JniNativeMethodRegistration ("n_onItemClick", "(Landroid/widget/AdapterView;Landroid/view/View;IJ)V", new Action<IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, IntPtr> (__<$>_jni_marshal_methods.n_onItemClick_Landroid_widget_AdapterView_Landroid_view_View_IJ)), new JniNativeMethodRegistration ("n_onItemLongClick", "(Landroid/widget/AdapterView;Landroid/view/View;IJ)Z", new Func<IntPtr, IntPtr, IntPtr, IntPtr, float, float, bool> (__<$>_jni_marshal_methods.n_onItemLongClick_Landroid_widget_AdapterView_Landroid_view_View_IJ)) }); } It's this mismatch which causes the runtime crash, and fixing `Extensions.CheckMethod()` to not require debug symbols allows all the methods to be found.
1 parent f4c953f commit 0b7f93b

File tree

1 file changed

+12
-0
lines changed
  • tools/jnimarshalmethod-gen

1 file changed

+12
-0
lines changed

tools/jnimarshalmethod-gen/App.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,9 @@ void CreateMarshalMethodAssembly (string path)
251251
continue;
252252
}
253253

254+
if (Verbose)
255+
ColorWriteLine ($"Processing {type} type", ConsoleColor.Yellow);
256+
254257
var registrationElements = new List<Expression> ();
255258
var targetType = Expression.Variable (typeof(Type), "targetType");
256259
TypeBuilder dt = null;
@@ -491,6 +494,15 @@ static bool CheckMethod (MethodDefinition m, ref string name, ref string methodN
491494

492495
}
493496

497+
if ((string.IsNullOrEmpty (name) || string.IsNullOrEmpty (signature)) && constructorArguments.Length != 3)
498+
continue;
499+
500+
if (string.IsNullOrEmpty (name))
501+
name = constructorArguments [0].Value.ToString ();
502+
503+
if (string.IsNullOrEmpty (signature))
504+
signature = constructorArguments [1].Value.ToString ();
505+
494506
if (string.IsNullOrEmpty (name) || string.IsNullOrEmpty (signature))
495507
continue;
496508

0 commit comments

Comments
 (0)