Skip to content

Commit 3d53762

Browse files
committed
Merge branch 'main' into tune-runtime-cpp
* main: Enable marshal methods support by default (dotnet#7351) Bump to dotnet/java-interop@e1ee4b1c, xamarin/android-api-docs@bc5443dc (dotnet#7358)
2 parents 12f8bd3 + 8bc7a3e commit 3d53762

File tree

5 files changed

+56
-27
lines changed

5 files changed

+56
-27
lines changed

Documentation/guides/building-apps/build-properties.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,15 @@ not wish to run those checks.
424424

425425
Added in Xamarin.Android 9.4.
426426

427+
## AndroidEnableMarshalMethods
428+
429+
A bool property, not available in the classic Xamarin.Android
430+
releases.
431+
432+
Enable or disable generation of [marshal
433+
methods](../../internals/JavaJNI_Interop.md). Defaults to `True` for
434+
`Release` builds and to `False` for `Debug` builds.
435+
427436
## AndroidEnableMultiDex
428437

429438
A boolean property that

Documentation/guides/internals/JavaJNI_Interop.md

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ are described in the sections below.
3232
This guide is meant to explain the technical implementation in a way
3333
that is sufficient to understand the system without having to read the
3434
actual source code.
35-
35+
3636
# Java <-> Managed interoperability overview
3737

3838
Java VM and Managed VM are two entirely separate entities which
@@ -104,9 +104,9 @@ public class MainActivity : AppCompatActivity
104104
protected override void OnCreate (Bundle savedInstanceState)
105105
{
106106
base.OnCreate(savedInstanceState);
107-
DoSomething (savedInstanceState);
107+
DoSomething (savedInstanceState);
108108
}
109-
109+
110110
void DoSomething (Bundle bundle)
111111
{
112112
// do something with the bundle
@@ -161,7 +161,7 @@ Java.Interop's [`JavaTypeScanner`](../../external/Java.Interop/src/Java.Interop.
161161
which uses `Mono.Cecil` to read all the assemblies referenced by the
162162
application and its libraries. The returned list of assemblies is
163163
then used by a variety of tasks, JCW being only one
164-
of them.
164+
of them.
165165

166166
After all types are found,
167167
[`JavaCallableWrapperGenerator`](../../external/Java.Interop/src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/JavaCallableWrapperGenerator.cs)
@@ -183,7 +183,7 @@ its constructor with three parameters:
183183
1. Java method name
184184
2. JNI method signature
185185
3. "Connector" method name
186-
186+
187187
The "connector" is a static method which creates a delegate that
188188
subsequently allows calling of the native callback method:
189189

@@ -509,7 +509,7 @@ static get_function_pointer_fn get_function_pointer;
509509

510510
void xamarin_app_init (get_function_pointer_fn fn) noexcept
511511
{
512-
get_function_pointer = fn;
512+
get_function_pointer = fn;
513513
}
514514

515515
using android_app_activity_on_create_bundle_fn = void (*) (JNIEnv *env, jclass klass, jobject savedInstanceState);
@@ -520,11 +520,11 @@ JNICALL Java_helloandroid_MainActivity_n_1onCreate__Landroid_os_Bundle_2 (JNIEnv
520520
{
521521
if (android_app_activity_on_create_bundle == nullptr) {
522522
get_function_pointer (
523-
16, // mono image index
524-
0, // class index
525-
0x0600055B, // method token
526-
reinterpret_cast<void*&>(android_app_activity_on_create_bundle) // target pointer
527-
);
523+
16, // mono image index
524+
0, // class index
525+
0x0600055B, // method token
526+
reinterpret_cast<void*&>(android_app_activity_on_create_bundle) // target pointer
527+
);
528528
}
529529

530530
android_app_activity_on_create_bundle (env, klass, savedInstanceState);
@@ -588,11 +588,13 @@ The exact modifications we apply are:
588588
589589
* Removal of the **connector backing field**
590590
* Removal of the **connector method**
591-
* Addition of the `[UnmanagedCallersOnly]` attribute to the **native
592-
callback** method
593-
* Optionally, generation of a [non-blittable types
594-
wrapper](#wrappers-for-methods-with-non-blittable-types) for the
595-
**native callback** method.
591+
* Generation of a **native callback wrapper** method, which catches
592+
and propagates unhandled exceptions thrown by the native callback
593+
or the target method. This method is decorated with the
594+
`[UnmanagedCallersOnly]` attribute and called directly from the
595+
native code.
596+
* Optionally, generate code in the **native callback wrapper** to handle
597+
[non-blittable types](#wrappers-for-methods-with-non-blittable-types).
596598
597599
All the modifications are performed with `Mono.Cecil`.
598600
@@ -603,14 +605,24 @@ C# code for each marshal method:
603605
public class MainActivity : AppCompatActivity
604606
{
605607
// Native callback
606-
[UnmanagedCallersOnly]
607608
static void n_OnCreate_Landroid_os_Bundle_ (IntPtr jnienv, IntPtr native__this, IntPtr native_savedInstanceState)
608609
{
609610
var __this = global::Java.Lang.Object.GetObject<Android.App.Activity> (jnienv, native__this, JniHandleOwnership.DoNotTransfer)!;
610611
var savedInstanceState = global::Java.Lang.Object.GetObject<Android.OS.Bundle> (native_savedInstanceState, JniHandleOwnership.DoNotTransfer);
611612
__this.OnCreate (savedInstanceState);
612613
}
613614
615+
// Native callback exception wrapper
616+
[UnmanagedCallersOnly]
617+
static void n_OnCreate_Landroid_os_Bundle__mm_wrapper (IntPtr jnienv, IntPtr native__this, IntPtr native_savedInstanceState)
618+
{
619+
try {
620+
n_OnCreate_Landroid_os_Bundle_ (jnienv, native__this, native_savedInstanceState)
621+
} catch (Exception ex) {
622+
Android.Runtime.AndroidEnvironmentInternal.UnhandledException (ex);
623+
}
624+
}
625+
614626
// Target method
615627
[Register ("onCreate", "(Landroid/os/Bundle;)V", "GetOnCreate_Landroid_os_Bundle_Handler")]
616628
protected virtual unsafe void OnCreate (Android.OS.Bundle? savedInstanceState)
@@ -665,13 +677,6 @@ value properly. Each wrapper method retains the native callback method
665677
name, but appends the `_mm_wrapper` suffix to it:
666678

667679
```csharp
668-
669-
[UnmanagedCallersOnly]
670-
static byte n_OnTouch_Landroid_view_View_Landroid_view_MotionEvent__mm_wrapper (IntPtr jnienv, IntPtr native__this, IntPtr native_v, IntPtr native_e)
671-
{
672-
return n_OnTouch_Landroid_view_View_Landroid_view_MotionEvent_(jnienv, native__this, native_v, native_e) ? 1 : 0;
673-
}
674-
675680
static bool n_OnTouch_Landroid_view_View_Landroid_view_MotionEvent_ (IntPtr jnienv, IntPtr native__this, IntPtr native_v, IntPtr native_e)
676681
{
677682
var __this = global::Java.Lang.Object.GetObject<Android.Views.View.IOnTouchListener> (jnienv, native__this, JniHandleOwnership.DoNotTransfer)!;
@@ -680,6 +685,17 @@ static bool n_OnTouch_Landroid_view_View_Landroid_view_MotionEvent_ (IntPtr jnie
680685
bool __ret = __this.OnTouch (v, e);
681686
return __ret;
682687
}
688+
689+
[UnmanagedCallersOnly]
690+
static byte n_OnTouch_Landroid_view_View_Landroid_view_MotionEvent__mm_wrapper (IntPtr jnienv, IntPtr native__this, IntPtr native_v, IntPtr native_e)
691+
{
692+
try {
693+
return n_OnTouch_Landroid_view_View_Landroid_view_MotionEvent_(jnienv, native__this, native_v, native_e) ? 1 : 0;
694+
} catch (Exception ex) {
695+
Android.Runtime.AndroidEnvironmentInternal.UnhandledException (ex);
696+
return default;
697+
}
698+
}
683699
```
684700

685701
The wrapper's return statement uses the ternary operator to "cast" the
@@ -738,7 +754,7 @@ Dynamic registration uses the
738754
[`RegisterNatives`](https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#RegisterNatives)
739755
JNI function at the runtime, which stores a pointer to the registered
740756
method inside the structure which describes a Java class in the Java
741-
VM.
757+
VM.
742758

743759
Marshal methods, however, don't register anything with the JNI,
744760
instead they rely on the symbol lookup mechanism of the Java VM.

external/Java.Interop

external/android-api-docs

Submodule android-api-docs updated 1782 files

src/monodroid/jni/monodroid-glue.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,10 @@ MonodroidRuntime::mono_runtime_init ([[maybe_unused]] dynamic_local_string<PROPE
837837
mono_jit_parse_options (static_cast<int>(aargs.size ()), aargs.data ());
838838
}
839839

840+
// int argc = 5;
841+
// char* argv[] = { "-v", "-v", "-v", "-v", "-v" };
842+
// mono_jit_parse_options (argc, argv);
843+
840844
mono_set_signal_chaining (1);
841845
mono_set_crash_chaining (1);
842846

0 commit comments

Comments
 (0)