Skip to content

Commit baa5a73

Browse files
authored
[marshal methods] Properly support arrays of arrays (#7707)
Fixes: #7693 Java code similar to: package com.xamarin.android; public interface DataListener { void onDataReceived ( java.lang.String fromNode, java.lang.String fromChannel, java.lang.String payloadType, byte[][] payload); } Generates a Java JNI signature with multiple `[`s: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[[B)V which then would throw our marshal methods native assembly generator off, because it didn't expect that there might be consecutive `[` characters for parameters which are arrays of arrays (of any rank): System.InvalidOperationException: Unsupported JNI array type '[' at index 56 of signature '(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[[B)V' error XAGPM7009: at Xamarin.Android.Tasks.MarshalMethodsNativeAssemblyGenerator.<ParseJniSignature>g__JniTypeToManaged|55_0(Char jniType, <>c__DisplayClass55_0&) error XAGPM7009: at Xamarin.Android.Tasks.MarshalMethodsNativeAssemblyGenerator.ParseJniSignature(String signature, MethodDefinition implementedMethod) error XAGPM7009: at Xamarin.Android.Tasks.MarshalMethodsNativeAssemblyGenerator.ProcessAndAddMethod(List`1 allMethods, MarshalMethodEntry entry, Boolean useFullNativeSignature, Dictionary`2 seenClasses, Dictionary`2 overloadedNativeSymbolNames) error XAGPM7009: at Xamarin.Android.Tasks.MarshalMethodsNativeAssemblyGenerator.Init() error XAGPM7009: at Xamarin.Android.Tasks.GeneratePackageManagerJava.AddEnvironment() error XAGPM7009: at Xamarin.Android.Tasks.GeneratePackageManagerJava.RunTask() error XAGPM7009: at Microsoft.Android.Build.Tasks.AndroidTask.Execute() in /Users/builder/azdo/_work/1/s/xamarin-android/external/xamarin-android-tools/src/Microsoft.Android.Build.BaseTasks/AndroidTask.cs:line 17 Fix this by skipping over the "extra" `[` characters. This generates code which uses a simple pointer to array, instead of a pointer to pointer etc. We can take this shortcut because we don't dereference the parameter in our generated code in any way, instead passing it as-is to the managed code.
1 parent 164e799 commit baa5a73

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

src/Xamarin.Android.Build.Tasks/Utilities/MarshalMethodsNativeAssemblyGenerator.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,13 @@ string MangleForJni (string name)
463463
}
464464

465465
if (jniType == '[') {
466-
idx++;
466+
// Arrays of arrays (any rank) are bound as a simple pointer, which makes the generated code much simpler (no need to generate pointers to
467+
// pointers to pointers etc), especially that we don't need to dereference these pointers in generated code, we simply pass them along to
468+
// the managed land after all.
469+
while (signature[idx] == '[') {
470+
idx++;
471+
}
472+
467473
jniType = signature[idx];
468474
if (jniArrayTypeMap.TryGetValue (jniType, out managedType)) {
469475
if (jniType == 'L') {

0 commit comments

Comments
 (0)