You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fixes: dotnet/android#7554
Placing `[Export]` on a constructor with parameters did not work as
expected. Consider:
public class Example : Java.Lang.Object
{
[Export(SuperArgumentsString = "")]
public Example (int value)
{
this.value = value;
}
int value;
}
This *does* generate a Java Callable Wrapper with the desired
constructor, but it *doesn't* invoke the correct C# constructor,
because of the `TypeManager.Activate()` invocation:
// Java JCW
/* partial */ class Example extends java.lang.Object {
public Example(int p0) {
super ();
if (getClass () == Example.class) {
mono.android.TypeManager.Activate (
/* typeName */ "Namespace.Example, Assembly",
/* signature */ "",
/* instance */ this,
/* parameterList */ new java.lang.Object[] { p0 });
}
}
}
In particular, because `signature` is the empty string,
`TypeManager.Activate()` will lookup and invoke the *default*
constructor, rather than the `Example(int)` constructor.
(This despite the fact that `parameterList` contains arguments!)
Consequently, when Java invokes the `Example(int)` constructor,
an exception is thrown, as the default constructor it wants doesn't
exist:
Could not activate JNI Handle 0x7ffd2bd94e50 (key_handle 0x65d856e) of Java type 'namespace/Example' as managed type 'Namespace.Example'.
Java.Interop.JavaLocationException: Exception of type 'Java.Interop.JavaLocationException' was thrown.
Java.Lang.Error: Exception of type 'Java.Lang.Error' was thrown.
--- End of managed Java.Lang.Error stack trace ---
java.lang.Error: Java callstack:
at mono.android.TypeManager.n_activate(Native Method)
at mono.android.TypeManager.Activate(TypeManager.java:7)
at namespace.Example.<init>(Example.java:0)
…
Update `JavaCallableWrapperGenerator.AddConstructor()` so that the
`managedParameters` value is provided to the `Signature` instance for
the `[Export]` constructor. This value is then inserted as the
`signature` parameter value, which will allow the correct constructor
to be invoked:
// Fixed Java JCW
/* partial */ class Example extends java.lang.Object {
public Example(int p0) {
super ();
if (getClass () == Example.class) {
mono.android.TypeManager.Activate (
/* typeName */ "Namespace.Example, Assembly",
/* signature */ "System.Int32, System.Runtime",
/* instance */ this,
/* parameterList */ new java.lang.Object[] { p0 });
}
}
}
Copy file name to clipboardExpand all lines: src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/JavaCallableWrapperGenerator.cs
Copy file name to clipboardExpand all lines: tests/Java.Interop.Tools.JavaCallableWrappers-Tests/Java.Interop.Tools.JavaCallableWrappers/JavaCallableWrapperGeneratorTests.cs
+3-3Lines changed: 3 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -449,7 +449,7 @@ public ExportsConstructors (int p0)
449
449
{
450
450
super (p0);
451
451
if (getClass () == ExportsConstructors.class) {
452
-
mono.android.TypeManager.Activate (""Xamarin.Android.ToolsTests.ExportsConstructors, Java.Interop.Tools.JavaCallableWrappers-Tests"", """", this, new java.lang.Object[] { p0 });
0 commit comments