Repository navigation
[Export] doesn't support float[] #1259
Description
Activity
Is there anything I can do to help to move this issue forward?
Some of these lines fixes the array item check part of the issue. https://gist.github.com/atsushieno/a69bff3afe0afc2e7893e26af61450a1
However the changes from at https://github.com/xamarin/monodroid/commit/0d547ce broke array conversion that I have no idea how to fix. @jonpryor
Repro:
FooBar.java (AndroidJavaSource):
package androidtest1; public class FooBar { public static void invokeJCW (Object instance) throws Exception { java.lang.reflect.Method [] methods = Class.forName("androidtest1.Example").getMethods (); for (int i = 0; i < methods.length; i++) if (methods [i].getName () == "SetRanges") { Object arg = new double [] {0, 1, 2}; methods [i].invoke (instance, "foo", arg, 4); return; } throw new Exception ("method does not exist"); } }MainActivity.cs:
protected override void OnCreate (Bundle savedInstanceState) { base.OnCreate (savedInstanceState); var methods = Java.Lang.Class.ForName ("androidtest1.FooBar") .GetMethods (); var invoker = methods.FirstOrDefault (_ => _.Name == "invokeJCW"); invoker.Invoke (null, new Example ()); } public class Example : Java.Lang.Object { [Export] public void SetRanges (string text, double [] args, double arg2) { } } }Ok.
FYI, cannot access this linkHowever the changes from at xamarin/monodroid@0d547ce broke array conversion
Seems like not too many people need this feature?
Sorry it is a private repo that only makes sense to the devs.
@atsushieno: I don't immediately see how or why that commit broke things. Before the change,
DynamicInvokeTypeInfo.jnienv_newarraywas aMethodInfotoJNIEnv.NewArray<T>(T[]), and should have been a generic method definition.After the change,
DynamicInvokeTypeInfo.jnienv_newarrayis aMethodInfotoJNIEnv.NewArray<T>(T[]), and is a generic method definition.In
System.Arrayterms:// Actually the `csharp` command, but close enough... // Ways to obtain the MethodInfo for System.Array.BinarySearch<T>(T[], int) var a = typeof(Array); // 1. Via Reflection + LINQ var bsr = a.GetMethods().First(m => m.IsGenericMethod && m.Name == "BinarySearch" && m.GetParameters().Length == 2); // 2: Via Delegate conversion + Delegate.Method public class E { public static MethodInfo GetBinarySearchT<T>(Func<T[], T, int> func) { return func.Method.GetGenericMethodDefinition (); } } var bsm = E.GetBinarySearchT<int>(Array.BinarySearch); // Results are the same, but mechanism 2 is much faster. Console.WriteLine(bsm == bsr); // true
The change, that you are quite aware of, therefore results in:
[MonoDroid] UNHANDLED EXCEPTION: [MonoDroid] System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: Call to method AndroidTest1.Example.SetRanges: Parameter 1. Can't cast from T[] to System.Double[] [MonoDroid] at Mono.CodeGeneration.CodeGenerationHelper.GenerateMethodCall (System.Reflection.Emit.ILGenerator gen, Mono.CodeGeneration.CodeExpression target, System.Reflection.MethodBase method, System.Type[] parameterTypes, Mono.CodeGeneration.CodeExpression[] parameters) [0x00118] in <19387e49dc8946eda9d7ad05203f74fb>:0 [MonoDroid] at Mono.CodeGeneration.CodeGenerationHelper.GenerateMethodCall (System.Reflection.Emit.ILGenerator gen, Mono.CodeGeneration.CodeExpression target, System.Reflection.MethodBase method, Mono.CodeGeneration.CodeExpression[] parameters) [0x00041] in <19387e49dc8946eda9d7ad05203f74fb>:0 [MonoDroid] at Mono.CodeGeneration.CodeMethodCall.Generate (System.Reflection.Emit.ILGenerator gen) [0x00029] in <19387e49dc8946eda9d7ad05203f74fb>:0 [MonoDroid] at Mono.CodeGeneration.CodeMethodCall.GenerateAsStatement (System.Reflection.Emit.ILGenerator gen) [0x00001] in <19387e49dc8946eda9d7ad05203f74fb>:0 [MonoDroid] at Mono.CodeGeneration.CodeBlock.Generate (System.Reflection.Emit.ILGenerator gen) [0x0002a] in <19387e49dc8946eda9d7ad05203f74fb>:0 [MonoDroid] at Mono.CodeGeneration.CodeBuilder.Generate (System.Reflection.Emit.ILGenerator gen) [0x00001] in <19387e49dc8946eda9d7ad05203f74fb>:0 [MonoDroid] at Mono.CodeGeneration.CodeMethod.Generate (System.Reflection.Emit.ILGenerator gen) [0x00015] in <19387e49dc8946eda9d7ad05203f74fb>:0 [MonoDroid] at Java.Interop.DynamicCallbackCodeGenerator.GenerateNativeCallbackDelegate () [0x000d3] in <19387e49dc8946eda9d7ad05203f74fb>:0 [MonoDroid] at Java.Interop.DynamicCallbackCodeGenerator.GetCallback () [0x0000e] in <19387e49dc8946eda9d7ad05203f74fb>:0 [MonoDroid] at Java.Interop.DynamicCallbackCodeGenerator.Create (System.Reflection.MethodInfo method) [0x00007] in <19387e49dc8946eda9d7ad05203f74fb>:0 [MonoDroid] at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke(System.Reflection.MonoMethod,object,object[],System.Exception&) [MonoDroid] at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00032] in <316413990ea1468fadc4a3d4de9c4235>:0@atsushieno: From what I can tell, the change should have had no semantic effect: before the change,
DynamicInvokeTypeInfo.jnienv_newarrayis aMethodInforeferring to the generic method definition forJNIEnv.NewArray<T>(T[]), and after the change it continues to be aMethodInforeferring to the generic method definition forJNIEnv.NewArray<T>(T[]).I do not believe that the commit you're referring to is responsible for the
System.InvalidOperationException. "Locally reverting" that patch should show that it has nothing to do with theInvalidOperationException, and would take ~5 minutes to verify. I cannot see why it would have anything to do with the problem.Furthermore, the only quick places I can find use of
CallbackCode.jnienv_newarrayis inCallbackCode.cs, e.g. withinDynamicInvokeTypeInfo.ToNative(). This location usesjnienv_newarray.MakeGenericMethod(), so the createdCodeMethodCall()shouldn't even be using a type parameter, it should be using a known type such asdouble.Additionally, if
DynamicInvokeTypeInfo.jnienv_newarrayweren't a generic method definition, then the.MakeGenericMethod()call would itself have been throwing. It isn't.Finally, I'm assuming you have a local patch to even be generating the above stack trace. What is that patch? Without any changes, we should be getting the originally mentioned
NotSupportedException.My stacktrace is based on the local patch I posted at #1259 (comment) . The patch also tells that there were method signature changes in JNIEnv GetArray() that resulted in method argument count mismatch. Therefore I noticed that there were incompatible API changes.
Currently md-addins broke debugger which makes it quite annoying to debug any issues.
Is there currently a workaround I could use regarding this?
No. I would completely avoid depending on any code that requires [Export] by writing managed code that overrides existing Java methods which would result in a working Java callable wrappers though.
Ok, thanks for the idea. Though I'm not sure this can work in my use case: C code calling JNI exposed code (which I intended to generate through [Export] attributes). There is no existing Java code per se.
I will look for another way.
For any native (C) functions P/Invoke just works.
That's not it, maybe I was not clear.
I'm not calling C from C# (in this case), C is calling me through JNI with https://github.com/videolan/vlc/blob/a16a24bce5e7e8fa6b2c05e63f5524e1d8df0640/modules/video_output/android/utils.c#L434
I guess my best bet then is to build the relevant java code into a .jar and put that in an Android binding library project. Thanks though.Same issue here when trying to export the following method:
[JavascriptInterface] [Export("log")] public void Log(params string[] data) { System.Diagnostics.Debug.WriteLine("NetworkView: " + string.Join(" ", data)); }Is this a regression? If so, could someone please point me where to find what version of Xamarin does not have this issue. Thanks.
Is there any updates regrading this issue?
Reacted by York Shen and Mai SwaitReacted by York Shen- addedArea: BindingsIssues in Java Library Binding projects.Issues in Java Library Binding projects.
on Oct 18, 2022 - addedpossibly-staleIssues that are potentially no longer relevant.Issues that are potentially no longer relevant.
on May 8, 2026 dotnet-policy-service commented
on May 8, 2026 More actionsWe suspect this issue is stale and no longer relevant. It will be closed if no further activity occurs within 14 more days. Any new comment (by anyone, not necessarily the author) will undo this process.
- locked and limited conversation to collaborators
on Jun 22, 2026
From: dotnet/java-interop#264
Steps to Reproduce
[Export]method which contains an array parameter.Expected Behavior
It works!
Actual Behavior
What's funny is that
float[]is a "primitive type" for array types.Related: https://github.com/xamarin/xamarin-android/blob/20123b569151eea9faaa859de902ca9b09a17a5d/src/Mono.Android.Export/CallbackCode.cs#L252