Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xamarin android binding interface method more than 16 parameter how to deal with delegate #631

Closed
jingliancui opened this issue Apr 21, 2020 · 11 comments · Fixed by #632 or dotnet/android#4631
Assignees
Labels
enhancement Proposed change to current functionality generator Issues binding a Java library (generator, class-parse, etc.)
Milestone

Comments

@jingliancui
Copy link

AndroidApp.zip the java code library sample i create

interfacelongmethodlibrary-debug.zip the java code library aar file i create

Steps to Reproduce

  1. Use Vs to create an binding project
  2. add this .aar file
  3. build
    4.show more than 16 parameter warning and method doesn't generated

I know how to deal the class with this warning,
But it's has an invoker of the interface,I didn't know how to deal with this situation.

Expect:
1.create a class inherited from this interface within the client project(Xamarin.android project).
2.invoke the Client Class' method to trigger the customer interface method.

@jingliancui
Copy link
Author

And the key I know is the Fun<> or Action<> just support 15 parameter, so I think you have something solution for this issue which method parameter more than 16 parameter.

@jonpryor
Copy link
Member

We need to move away from Func<…>/Action<…> anyway, because our current use only works on Mono, not .NET Framework or .NET Core, and an intention is for Java.Interop to be usable in "normal" desktop environments.

.NET Core intends on introducing a new "more performant" replacement:

but I don't see how we can easily use that new infrastructure while continuing to use System.Reflection.Emit within src/Mono.Android/Android.Runtime/JNINativeWrapper.cs, so that's a "long term" idea (probably to also fold into jnimarshalmethod-gen.exe).

Meaning we need to stick with delegates. Non-generic delegates at that.

@jonpryor
Copy link
Member

jonpryor commented Apr 21, 2020

Implementation approach: within generator, instead of hardcoding Action and Func use, we instead need a "2 pass" design.

We define a pattern for defining delegate type names:

  • Type name prefix: _JniMarshal_PP
  • Parameter types, using JNI encoding, e.g. Z is boolean, I is int, etc. Exception: Reference types, normally encoded as L…;, are instead just L.
  • Another _.
  • Return type, encoded as with parameters. A void return type is V.

Consider, Java.Lang.Object.Equals():

static Delegate GetEquals_Ljava_lang_Object_Handler ()
{
	if (cb_equals_Ljava_lang_Object_ == null)
		cb_equals_Ljava_lang_Object_ = JNINativeWrapper.CreateDelegate ((Func<IntPtr, IntPtr, IntPtr, bool>) n_Equals_Ljava_lang_Object_);
	return cb_equals_Ljava_lang_Object_;
}

The delegate type on line 4 would instead be _JniMarshal_PPL_Z, resulting in:

static Delegate GetEquals_Ljava_lang_Object_Handler ()
{
	if (cb_equals_Ljava_lang_Object_ == null)
		cb_equals_Ljava_lang_Object_ = JNINativeWrapper.CreateDelegate ((_JniMarshal_PPL_Z) n_Equals_Ljava_lang_Object_);
	return cb_equals_Ljava_lang_Object_;
}

That's the "first" pass.

The second pass is that we need to collect all the types that we're now mentioning in ^^, and then emit them as global internal types:

delegate bool _JniMarshal_PPL_Z (IntPtr jnienv, IntPtr klass, IntPtr a);

This second pass is the "interesting" bit, in that it raises the question: where should these be declared? They could probably be defined in __NamespaceMapping__.cs.

@jpobst jpobst transferred this issue from dotnet/android Apr 21, 2020
@jpobst jpobst added enhancement Proposed change to current functionality generator Issues binding a Java library (generator, class-parse, etc.) labels Apr 21, 2020
@jingliancui
Copy link
Author

@jonpryor

delegate bool _JniMarshal_PPL_Z (IntPtr jnienv, IntPtr klass, IntPtr a);

but the a which is Intptr parameter now map to 16 int args in the aar library.

Now, in debug , I can get the first Intptr value is 0x1 which is I parse value 1 in java code.

But,How to get others paramenter values?
And another question is possible get all value while the 16 parameter have different type ,for example:
int i1,java.lang.string i2,com.others.other.Obj i3 ........ etc.

@jingliancui
Copy link
Author

That the binding project I create
InterfaceLongMethodBinding.zip

@jingliancui
Copy link
Author

take breakpoint at
App1.Droid.MainActivity line 25,26,27
InterfaceLongMethodBinding/Additions/IInterfaceOne line 96

@jonpryor
Copy link
Member

@jingliancui
Copy link
Author

@jonpryor Fixed it by your workaround, thanks.

@jingliancui
Copy link
Author

Is it necessary need this attribute?
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
I try remove this and app run fine , What does this do?

jonpryor pushed a commit that referenced this issue Apr 28, 2020
Fixes: #631

Context: dotnet/runtime#32963
Context: https://github.com/dotnet/csharplang/blob/master/proposals/function-pointers.md

*Of `Delegate`s and JNI Callbacks…*

~~ Background ~~

In order for Java code to invoke Managed Code such as C#, several
things must happen:

 1. There must be a Java class which declares `native` methods.
 2. The Java class' `native` methods must be [*resolvable*][0]

Java `native` method resolution can be done by [C function name][1]
*or* by using [`JNIEnv::RegisterNatives()`][2]:

	// C++
	struct JNINativeMethod {
	    const char *name;
	    const char *signature;
	    const void *fnPtr;
	};

	/* partial */ struct JNIEnv {
	    jint RegisterNatives(jclass clazz, const JNINativeMethod *methods, jint nMethods);
	};

`JNINativeMethods::fnPtr` is a pointer to a *C callable function*
that accepts [JNI Native Method Arguments][3].

Java.Interop doesn't currently support resolution via C function name,
and instead binds the `JNINativeMethod` struct as
`JniNativeMethodRegistration`, and `JNIEnv::RegisterNatives()` as
`Java.Interop.JniEnvironment.Types.RegisterNatives()`:

	// C#
	public partial struct JniNativeMethodRegistration {
	    public  string    Name;
	    public  string    Signature;
	    public  Delegate  Marshaler;
	}
	public partial class JniEnvironment {
	    public partial class Types {
	        public static void RegisterNatives (JniObjectReference type, JniNativeMethodRegistration [] methods);
	    }
	}

Through the glory that is [Platform Invoke Delegate Marshaling][4]
and/or [`Marshal.GetFunctionPointerForDelegate()`][5], managed code
can provide a `Delegate` instance in
`JniNativeMethodRegistration.Marshaler` and have JNI invoke that
delegate when the corresponding Java `native` method is invoked.

`tools/generator` is responsible for emitting this glue code, e.g.
in order to support registering overrides of
[`java.lang.Object.equals()`][6]:

	// C# emitted by `tools/generator`:
	namespace Java.Lang {
	  partial class Object {
	    static Delegate cb_equals_Ljava_lang_Object_;
	    static Delegate GetEquals_Ljava_lang_Object_Handler ()
	    {
	      if (cb_equals_Ljava_lang_Object_ == null)
	        cb_equals_Ljava_lang_Object_ = JNINativeWrapper.CreateDelegate ((Func<IntPtr, IntPtr, IntPtr, bool>) n_Equals_Ljava_lang_Object_);
	      return cb_equals_Ljava_lang_Object_;
	    }

	    static bool n_Equals_Ljava_lang_Object_ (IntPtr jnienv, IntPtr native__this, IntPtr native_obj)
	    {
	      var __this = global::Java.Lang.Object.GetObject<Java.Lang.Object> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
	      var obj = global::Java.Lang.Object.GetObject<Java.Lang.Object> (native_obj, JniHandleOwnership.DoNotTransfer);
	      bool __ret = __this.Equals (obj);
	      return __ret;
	    }
	  }
	}

`Object.n_Equals_Ljava_lang_Object()` is stored in a
`Func<IntPtr, IntPtr, IntPtr, bool>` -- which conforms to JNI Native
Method Arguments -- and is then provided to
[`JNINativeWrapper.CreateDelegate()`][7], which uses
`System.Reflection.Emit` to "wrap" `n_Equals_Ljava_lang_Object()` for
exception propagation purposes.  Eventually and ultimately, when a C#
class overrides `Java.Lang.Object.Equals()`,
`Object.GetEquals_Ljava_lang_Object_Handler()` will be invoked at
runtime, and `Object.cb_equals_Ljava_lang_Object` will be stored into
`JniNativeMethodRegistration.Marshaler`.


~~ `Action<…>` and `Func<…>` ~~

There is one problem with the above approach: its use of the
`System.Action<…>` and `System.Func<…>` types used at the core of
registering native methods with JNI.  There are two problems with
using these sets of types:

 1. These delegate types only permit up to 16 parameters.  Given that
    *two* parameters are always "eaten" by the `JNIEnv*` pointer and
    a `jobject` to Java's `this` or a `jclass` to the declaring class,
    that means that we can only bind methods taking up to 14 methods.
    Java methods which take more than 14 methods are skipped.

 2. .NET Framework and CoreCLR don't support using generic types with
    the Platform Invoke marshaler and
    [`Marshal.GetFunctionPointerForDelegate()`][8].

(1) has been a longstanding problem, which we've been ignoring.

(2) isn't *yet* a problem, and is something @jonpryor has been keen
to address for awhile.


~~ C# Function Pointers? ~~

There is a proposal to [add Function Pointers to the C# language][9].
This would permit reduced overheads and improved efficiencies in
obtaining a function pointer to pass into Java code.

Unfortunately:

 1. The proposal is still ongoing, with no known release date.
 2. .NET Framework 4.x won't support them.
 3. They can't be used within the current Xamarin.Android architecture.

There doesn't appear to be a way to obtain a `Delegate` from a
`delegate*`, which means `JNINativeWrapper.CreateDelegate()` cannot
be used with Function Pointers.

In order to use Function Pointers, we would likely need to *require*
use of `tools/jnimarshalmethod-gen.exe` (176240d) so that appropriate
JNI Native Method Argument-conforming methods with the
`NativeCallableAttribute` can be generated at app build time,
*avoiding* the current Reflection-heavy registration path which
involves e.g. `Object.GetEquals_Ljava_lang_Object_Handler()`.

Unfortunately, `jnimarshalmethod-gen.exe` isn't "done": it doesn't
work on Windows, and it's use of `AppDomain`s and
`System.Reflection.Emit` look to complicate a future .NET 5 port.


~~ Solution: Generate Delegates ~~

If `Action<…>` and `Func<…>` are to be avoided, and Function Pointers
are out, how do we support more than 14 parameters?

By updating `generator` to emit the required delegate types.

When `Action<…>` or `Func<…>` would previously have been generated,
instead emit *and record the name of* a delegate which follows the
pattern:

  * Type name prefix: `_JniMarshal_PP`
  * Parameter types, using JNI encoding, e.g. `Z` for boolean,
    `I` for int, etc.  *Reference types*, normally encoded as `L…;`
    and Arrays, encoded as `[`, are each encoded as `L`.
    Kotlin unsigned types are encoded as *lower-case* forms of the
    corresponding JNI types, e.g. `i` is an unsigned `I`.
  * Another `_`.
  * The above type encoding for the return type.

For example, `Object.n_Equals_Ljava_lang_Object()` used
`Func<IntPtr, IntPtr, IntPtr, bool>`.  This would become
`_JniMarshal_PPL_Z`.

After the initial binding stage is complete and all required delegate
types are recorded, the `_JniMarshal*` types are emitted into
`__NamespaceMapping__.cs`:

	internal delegate bool _JniMarshal_PPL_Z (IntPtr jnienv, IntPtr klass, IntPtr a);

The cost to declaring all these types is that a binding assembly
contains more types.  `Mono.Android.dll`, for example, grows ~20KB
in size from all the required delegate declarations, pre-linking.


~~ Other ~~

Remove `tools/generator/generator.sln` and replace it with a
`tools/generator/generator.slnf` solution filter file which makes it
easier to work with `generator` in Visual Studio by only loading
needed projects from `Java.Interop.sln`.


[0]: https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#compiling_loading_and_linking_native_methods
[1]: https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#resolving_native_method_names
[2]: https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#RegisterNatives
[3]: https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#native_method_arguments
[4]: https://docs.microsoft.com/en-us/dotnet/framework/interop/marshaling-a-delegate-as-a-callback-method
[5]: https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.marshal.getfunctionpointerfordelegate?view=netcore-3.1
[6]: https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals%28java.lang.Object%29
[7]: https://github.com/xamarin/xamarin-android/blob/42822e0488185cdf4bca7c0bd05b21ad03dfbd7e/src/Mono.Android/Android.Runtime/JNINativeWrapper.cs#L34-L97
[8]: dotnet/runtime#32963
[9]: https://github.com/dotnet/csharplang/blob/master/proposals/function-pointers.md
jonpryor added a commit to jonpryor/xamarin-android that referenced this issue Apr 28, 2020
Changes: dotnet/java-interop@ce8dc40...56955d9

Fixes: dotnet/java-interop#631

  * dotnet/java-interop@56955d9: [generator] Use custom delegates instead of Func/Action. (dotnet#632)
  * dotnet/java-interop@0a77166: [Java.Interop.sln] Commit updated automatically generated guids. (dotnet#634)
jonpryor added a commit to jonpryor/xamarin-android that referenced this issue May 1, 2020
Changes: dotnet/java-interop@ce8dc40...377c4c7

Fixes: dotnet/java-interop#631

  * dotnet/java-interop@377c4c7: Bump to xamarin/xamarin-android-tools/master@f5fcb9fd (dotnet#637)
  * dotnet/java-interop@857b9a9: [Java.Interop.Export] Begin supporting methods with 14+ params (dotnet#635)
  * dotnet/java-interop@9876e31: [Java.Interop.BootstrapTasks] Convert to SDK style project (dotnet#609)
  * dotnet/java-interop@cbb50af: [generator-Tests] Use Roslyn for .NET Core Support (dotnet#638)
  * dotnet/java-interop@56955d9: [generator] Use custom delegates instead of Func/Action. (dotnet#632)
  * dotnet/java-interop@0a77166: [Java.Interop.sln] Commit updated automatically generated guids. (dotnet#634)
jonpryor added a commit to jonpryor/xamarin-android that referenced this issue May 1, 2020
Changes: dotnet/java-interop@ce8dc40...377c4c7

Fixes: dotnet/java-interop#631

  * dotnet/java-interop@377c4c7: Bump to xamarin/xamarin-android-tools/master@f5fcb9fd (dotnet#637)
  * dotnet/java-interop@857b9a9: [Java.Interop.Export] Begin supporting methods with 14+ params (dotnet#635)
  * dotnet/java-interop@9876e31: [Java.Interop.BootstrapTasks] Convert to SDK style project (dotnet#609)
  * dotnet/java-interop@cbb50af: [generator-Tests] Use Roslyn for .NET Core Support (dotnet#638)
  * dotnet/java-interop@56955d9: [generator] Use custom delegates instead of Func/Action. (dotnet#632)
  * dotnet/java-interop@0a77166: [Java.Interop.sln] Commit updated automatically generated guids. (dotnet#634)
jonpryor added a commit to dotnet/android that referenced this issue May 2, 2020
Changes: dotnet/java-interop@ce8dc40...377c4c7

Fixes: dotnet/java-interop#631

  * dotnet/java-interop@377c4c7: Bump to xamarin/xamarin-android-tools/master@f5fcb9fd (#637)
  * dotnet/java-interop@857b9a9: [Java.Interop.Export] Begin supporting methods with 14+ params (#635)
  * dotnet/java-interop@9876e31: [Java.Interop.BootstrapTasks] Convert to SDK style project (#609)
  * dotnet/java-interop@cbb50af: [generator-Tests] Use Roslyn for .NET Core Support (#638)
  * dotnet/java-interop@56955d9: [generator] Use custom delegates instead of Func/Action. (#632)
  * dotnet/java-interop@0a77166: [Java.Interop.sln] Commit updated automatically generated guids. (#634)
jonpryor pushed a commit that referenced this issue May 6, 2020
Fixes: #631

Context: dotnet/runtime#32963
Context: https://github.com/dotnet/csharplang/blob/master/proposals/function-pointers.md

*Of `Delegate`s and JNI Callbacks…*

~~ Background ~~

In order for Java code to invoke Managed Code such as C#, several
things must happen:

 1. There must be a Java class which declares `native` methods.
 2. The Java class' `native` methods must be [*resolvable*][0]

Java `native` method resolution can be done by [C function name][1]
*or* by using [`JNIEnv::RegisterNatives()`][2]:

	// C++
	struct JNINativeMethod {
	    const char *name;
	    const char *signature;
	    const void *fnPtr;
	};

	/* partial */ struct JNIEnv {
	    jint RegisterNatives(jclass clazz, const JNINativeMethod *methods, jint nMethods);
	};

`JNINativeMethods::fnPtr` is a pointer to a *C callable function*
that accepts [JNI Native Method Arguments][3].

Java.Interop doesn't currently support resolution via C function name,
and instead binds the `JNINativeMethod` struct as
`JniNativeMethodRegistration`, and `JNIEnv::RegisterNatives()` as
`Java.Interop.JniEnvironment.Types.RegisterNatives()`:

	// C#
	public partial struct JniNativeMethodRegistration {
	    public  string    Name;
	    public  string    Signature;
	    public  Delegate  Marshaler;
	}
	public partial class JniEnvironment {
	    public partial class Types {
	        public static void RegisterNatives (JniObjectReference type, JniNativeMethodRegistration [] methods);
	    }
	}

Through the glory that is [Platform Invoke Delegate Marshaling][4]
and/or [`Marshal.GetFunctionPointerForDelegate()`][5], managed code
can provide a `Delegate` instance in
`JniNativeMethodRegistration.Marshaler` and have JNI invoke that
delegate when the corresponding Java `native` method is invoked.

`tools/generator` is responsible for emitting this glue code, e.g.
in order to support registering overrides of
[`java.lang.Object.equals()`][6]:

	// C# emitted by `tools/generator`:
	namespace Java.Lang {
	  partial class Object {
	    static Delegate cb_equals_Ljava_lang_Object_;
	    static Delegate GetEquals_Ljava_lang_Object_Handler ()
	    {
	      if (cb_equals_Ljava_lang_Object_ == null)
	        cb_equals_Ljava_lang_Object_ = JNINativeWrapper.CreateDelegate ((Func<IntPtr, IntPtr, IntPtr, bool>) n_Equals_Ljava_lang_Object_);
	      return cb_equals_Ljava_lang_Object_;
	    }

	    static bool n_Equals_Ljava_lang_Object_ (IntPtr jnienv, IntPtr native__this, IntPtr native_obj)
	    {
	      var __this = global::Java.Lang.Object.GetObject<Java.Lang.Object> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
	      var obj = global::Java.Lang.Object.GetObject<Java.Lang.Object> (native_obj, JniHandleOwnership.DoNotTransfer);
	      bool __ret = __this.Equals (obj);
	      return __ret;
	    }
	  }
	}

`Object.n_Equals_Ljava_lang_Object()` is stored in a
`Func<IntPtr, IntPtr, IntPtr, bool>` -- which conforms to JNI Native
Method Arguments -- and is then provided to
[`JNINativeWrapper.CreateDelegate()`][7], which uses
`System.Reflection.Emit` to "wrap" `n_Equals_Ljava_lang_Object()` for
exception propagation purposes.  Eventually and ultimately, when a C#
class overrides `Java.Lang.Object.Equals()`,
`Object.GetEquals_Ljava_lang_Object_Handler()` will be invoked at
runtime, and `Object.cb_equals_Ljava_lang_Object` will be stored into
`JniNativeMethodRegistration.Marshaler`.


~~ `Action<…>` and `Func<…>` ~~

There is one problem with the above approach: its use of the
`System.Action<…>` and `System.Func<…>` types used at the core of
registering native methods with JNI.  There are two problems with
using these sets of types:

 1. These delegate types only permit up to 16 parameters.  Given that
    *two* parameters are always "eaten" by the `JNIEnv*` pointer and
    a `jobject` to Java's `this` or a `jclass` to the declaring class,
    that means that we can only bind methods taking up to 14 methods.
    Java methods which take more than 14 methods are skipped.

 2. .NET Framework and CoreCLR don't support using generic types with
    the Platform Invoke marshaler and
    [`Marshal.GetFunctionPointerForDelegate()`][8].

(1) has been a longstanding problem, which we've been ignoring.

(2) isn't *yet* a problem, and is something @jonpryor has been keen
to address for awhile.


~~ C# Function Pointers? ~~

There is a proposal to [add Function Pointers to the C# language][9].
This would permit reduced overheads and improved efficiencies in
obtaining a function pointer to pass into Java code.

Unfortunately:

 1. The proposal is still ongoing, with no known release date.
 2. .NET Framework 4.x won't support them.
 3. They can't be used within the current Xamarin.Android architecture.

There doesn't appear to be a way to obtain a `Delegate` from a
`delegate*`, which means `JNINativeWrapper.CreateDelegate()` cannot
be used with Function Pointers.

In order to use Function Pointers, we would likely need to *require*
use of `tools/jnimarshalmethod-gen.exe` (176240d) so that appropriate
JNI Native Method Argument-conforming methods with the
`NativeCallableAttribute` can be generated at app build time,
*avoiding* the current Reflection-heavy registration path which
involves e.g. `Object.GetEquals_Ljava_lang_Object_Handler()`.

Unfortunately, `jnimarshalmethod-gen.exe` isn't "done": it doesn't
work on Windows, and it's use of `AppDomain`s and
`System.Reflection.Emit` look to complicate a future .NET 5 port.


~~ Solution: Generate Delegates ~~

If `Action<…>` and `Func<…>` are to be avoided, and Function Pointers
are out, how do we support more than 14 parameters?

By updating `generator` to emit the required delegate types.

When `Action<…>` or `Func<…>` would previously have been generated,
instead emit *and record the name of* a delegate which follows the
pattern:

  * Type name prefix: `_JniMarshal_PP`
  * Parameter types, using JNI encoding, e.g. `Z` for boolean,
    `I` for int, etc.  *Reference types*, normally encoded as `L…;`
    and Arrays, encoded as `[`, are each encoded as `L`.
    Kotlin unsigned types are encoded as *lower-case* forms of the
    corresponding JNI types, e.g. `i` is an unsigned `I`.
  * Another `_`.
  * The above type encoding for the return type.

For example, `Object.n_Equals_Ljava_lang_Object()` used
`Func<IntPtr, IntPtr, IntPtr, bool>`.  This would become
`_JniMarshal_PPL_Z`.

After the initial binding stage is complete and all required delegate
types are recorded, the `_JniMarshal*` types are emitted into
`__NamespaceMapping__.cs`:

	internal delegate bool _JniMarshal_PPL_Z (IntPtr jnienv, IntPtr klass, IntPtr a);

The cost to declaring all these types is that a binding assembly
contains more types.  `Mono.Android.dll`, for example, grows ~20KB
in size from all the required delegate declarations, pre-linking.


~~ Other ~~

Remove `tools/generator/generator.sln` and replace it with a
`tools/generator/generator.slnf` solution filter file which makes it
easier to work with `generator` in Visual Studio by only loading
needed projects from `Java.Interop.sln`.


[0]: https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#compiling_loading_and_linking_native_methods
[1]: https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#resolving_native_method_names
[2]: https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#RegisterNatives
[3]: https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#native_method_arguments
[4]: https://docs.microsoft.com/en-us/dotnet/framework/interop/marshaling-a-delegate-as-a-callback-method
[5]: https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.marshal.getfunctionpointerfordelegate?view=netcore-3.1
[6]: https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals%28java.lang.Object%29
[7]: https://github.com/xamarin/xamarin-android/blob/42822e0488185cdf4bca7c0bd05b21ad03dfbd7e/src/Mono.Android/Android.Runtime/JNINativeWrapper.cs#L34-L97
[8]: dotnet/runtime#32963
[9]: https://github.com/dotnet/csharplang/blob/master/proposals/function-pointers.md
jonpryor added a commit to dotnet/android that referenced this issue May 6, 2020
Changes: dotnet/java-interop@6608c59...e599781

Fixes: dotnet/java-interop#631

  * dotnet/java-interop@e599781: Bump to xamarin/xamarin-android-tools/master@f5fcb9fd (#637)
  * dotnet/java-interop@b7aec95: [Java.Interop.Export] Begin supporting methods with 14+ params (#635)
  * dotnet/java-interop@eb6202b: [Java.Interop.BootstrapTasks] Convert to SDK style project (#609)
  * dotnet/java-interop@e078618: [generator-Tests] Use Roslyn for .NET Core Support (#638)
  * dotnet/java-interop@8e5310b: [generator] Use custom delegates instead of Func/Action. (#632)
  * dotnet/java-interop@f20f853: [Java.Interop.sln] Commit updated automatically generated guids. (#634)
@brendanzagaeski
Copy link
Contributor

Release status update

A new Preview version of Xamarin.Android has now been published that includes the fix for this item. The fix is not yet included in a Release version. I will update this again when a Release version is available that includes the fix.

Fix included in Xamarin.Android 10.3.99.259.

Fix included on Windows in Visual Studio 2019 version 16.7 Preview 2. To try the Preview version that includes the fix, check for the latest updates in Visual Studio Preview.

Fix included on macOS in Visual Studio 2019 for Mac version 8.7 Preview 2. To try the Preview version that includes the fix, check for the latest updates on the Preview updater channel.

@brendanzagaeski brendanzagaeski added this to the 10.4 (16.7 / 8.7) milestone Jun 3, 2020
@brendanzagaeski
Copy link
Contributor

Release status update

A new Release version of Xamarin.Android has now been published that includes the fix for this item.

Fix included in Xamarin.Android SDK version 11.0.0.3.

Fix included on Windows in Visual Studio 2019 version 16.7. To get the new version that includes the fix, check for the latest updates or install the most recent release from https://visualstudio.microsoft.com/downloads/.

Fix included on macOS in Visual Studio 2019 for Mac version 8.7. To get the new version that includes the fix, check for the latest updates on the Stable updater channel.

@github-actions github-actions bot locked and limited conversation to collaborators Apr 13, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement Proposed change to current functionality generator Issues binding a Java library (generator, class-parse, etc.)
Projects
None yet
4 participants