Embeddinator-4000 icon indicating copy to clipboard operation
Embeddinator-4000 copied to clipboard

[Android] Support array types for Java.Lang.Object types

Open Zomb opened this issue 7 years ago • 10 comments

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

Zomb avatar Oct 06 '17 13:10 Zomb

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).

tritao avatar Oct 06 '17 13:10 tritao

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);

Zomb avatar Oct 06 '17 13:10 Zomb

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.

tritao avatar Oct 06 '17 13:10 tritao

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?

Zomb avatar Oct 06 '17 13:10 Zomb

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.

tritao avatar Oct 06 '17 13:10 tritao

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.

Zomb avatar Oct 06 '17 14:10 Zomb

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?

tritao avatar Oct 06 '17 14:10 tritao

Yes, it says primitive types are allowed, but when I use a primitive type it errors out, and I was not sure why.

Zomb avatar Oct 06 '17 14:10 Zomb

@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.

jonathanpeppers avatar Oct 06 '17 15:10 jonathanpeppers

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!

mfkl avatar Jan 27 '18 18:01 mfkl