Embeddinator-4000
Embeddinator-4000 copied to clipboard
[Android] Support array types for Java.Lang.Object types
If I use an array as an argument for a C# method, for example:
[Export("parseData")]
public void ParseData(byte[] vendorData)
or
[Export("parseData")]
public void ParseData(int[] vendorData)
e4k completes successfully and generates the aar. Once I include it in my AS project and run the app, I get the following exception. I am using primitives as my type, so I am not sure what is causing the issue.
E/mono: Unhandled Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NotSupportedException: Only primitive types and IJavaObject is supported in array type in callback method parameter or return value at Java.Interop.DynamicInvokeTypeInfo.GetCallbackCleanup (System.Type type, Mono.CodeGeneration.CodeExpression arg, Mono.CodeGeneration.CodeExpression orgArg) [0x00031] in <33a53599dc2a4aa68ea5304041ec3a65>:0 at Java.Interop.DynamicInvokeTypeInfo.CleanupCallback (Mono.CodeGeneration.CodeExpression arg, Mono.CodeGeneration.CodeExpression orgArg) [0x00000] in <33a53599dc2a4aa68ea5304041ec3a65>:0 at Java.Interop.DynamicCallbackCodeGenerator.GenerateNativeCallbackDelegate (System.String generatedMethodName) [0x00219] in <33a53599dc2a4aa68ea5304041ec3a65>:0 at Java.Interop.DynamicCallbackCodeGenerator.GenerateNativeCallbackDelegate () [0x0009b] in <33a53599dc2a4aa68ea5304041ec3a65>:0 at Java.Interop.DynamicCallbackCodeGenerator.GetCallback () [0x00008] in <33a53599dc2a4aa68ea5304041ec3a65>:0 at Java.Interop.DynamicCallbackCodeGenerator.Create (System.Reflection.MethodInfo method) [0x00006] in <33a53599dc2a4aa68ea5304041ec3a65>:0 at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&) 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 <8a9b47e6e83b4973b835cda3f53125a0>:0 --- End of inner exception stack trace --- at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0004b] in <8a9b47e6e83b4973b835cda3f53125a0>:0 at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <8a9b47e6e83b4973b835cda3f53125a0>:0 at Android.Runtime.JNIEnv.CreateDynamicCallback (System.Reflection.MethodInfo method) [0x00070] in
:0 at Android.Runtime.JNIEnv.RegisterJniNatives (System.IntPtr typeName_ptr, System.Int32 typeName_len, System.IntPtr jniClass, System.IntPtr methods_ptr, System.Int32 methods_len) [0x001b1] in :0 E/mono-rt: [ERROR] FATAL UNHANDLED EXCEPTION: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NotSupportedException: Only primitive types and IJavaObject is supported in array type in callback method parameter or return value at Java.Interop.DynamicInvokeTypeInfo.GetCallbackCleanup (System.Type type, Mono.CodeGeneration.CodeExpression arg, Mono.CodeGeneration.CodeExpression orgArg) [0x00031] in <33a53599dc2a4aa68ea5304041ec3a65>:0 at Java.Interop.DynamicInvokeTypeInfo.CleanupCallback (Mono.CodeGeneration.CodeExpression arg, Mono.CodeGeneration.CodeExpression orgArg) [0x00000] in <33a53599dc2a4aa68ea5304041ec3a65>:0 at Java.Interop.DynamicCallbackCodeGenerator.GenerateNativeCallbackDelegate (System.String generatedMethodName) [0x00219] in <33a53599dc2a4aa68ea5304041ec3a65>:0 at Java.Interop.DynamicCallbackCodeGenerator.GenerateNativeCallbackDelegate () [0x0009b] in <33a53599dc2a4aa68ea5304041ec3a65>:0 at Java.Interop.DynamicCallbackCodeGenerator.GetCallback () [0x00008] in <33a53599dc2a4aa68ea5304041ec3a65>:0 at Java.Interop.DynamicCallbackCodeGenerator.Create (System.Reflection.MethodInfo method) [0x00006] in <33a53599dc2a4aa68ea5304041ec3a65>:0 at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&) 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 <8a9b47e6e83b4973b835cda3f53125a0>:0 --- End of inner exception stack trace --- at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0004b] in <8a9b47e6e83b4973b835cda3f53125a0>:0 at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <8a9b47e6e83b4973b835cda3f53125a0>:0 at Android.Runtime.JNIEnv.CreateDynamicCallback (System.Reflection.MethodInfo method) [0x00070] in :0 at Android.Runtime.JNIEnv.RegisterJniNatives (System.IntPtr typeName_ptr, System.Int32 typeName_len, System.IntPtr jniClass, System.IntPtr methods_ptr, System.Int32 methods_len) [0x001b1] in :0
Hey, arrays are still not supported in Java. It's the next feature to be supported (PR https://github.com/mono/Embeddinator-4000/pull/508).
Great! My current workaround for anyone else who runs into this right now is convert the array into a Base64String and back again.
var fromBase64String = Convert.FromBase64String(data);
Actually, looking again at the stack trace, this error seems related to arrays in Java.Lang.Object derived types, right? If that's the case, then my PR only implements support for non-Java.Lang.Object derived C# types.
Yes, the C# class that contains this derives from Java.Lang.Object because it needs to run on a background thread, and that's the only way to make that work according to @jonathanpeppers as documented in #439. Would this be a bug then? Or a new feature request?
I changed the title to track the issue more accurately. Not sure when this might be fixed though because it's not a limitation of Embeddinator generator itself but of the interop generator from Xamarin.Android.
Okay! In the change that you made, you said 'non-primitive array types' but I am running into the issue when my array is of type byte or int. I haven't tried using non-primitive types in an array.
I was going through the exception message in the trace you posted: Only primitive types and IJavaObject is supported in array type in callback method parameter or return value
.
Maybe this is not accurate after all?
Yes, it says primitive types are allowed, but when I use a primitive type it errors out, and I was not sure why.
@Zomb I'll try this out next week and write a test for it. I vaguely remember seeing something that was fixed in this area in Xamarin.Android.
So updating Xamarin.Android might fix it:
- We could update to Xamarin.Android 15-4 branch (equivalent of preview or beta of VS)
- We are getting really close to 15-4 hitting stable anyway, so dropping the
external/Xamarin.Android
folder completely would be nice
Of course if it's still broken on XA master, I can ask the right people.
Any news about this? Any workaround?
I get the same message on Xamarin.Android Only primitive types and IJavaObject is supported in array type in callback method parameter or return value
. Need to expose a method that has an array of float as parameter.
Thanks!