Pass a byte array to Android plugin in C# script

I am trying to write an Android plugin (.aar) for Unity3D and pass a byte array out of C# to a Java method, which is supposed to fill it with data.

//C# code:
byte[] buffer = new byte[1024];
int bytesRead = myJavaObject.Call<int>( "read", buffer );
//buffer contains only zeros

//Java code:
public int read( byte[] buffer )
    //fill buffer here...
    return numOfBytesRead;

What I get in my logcat is this:

2020-02-12 16:41:22.717 23831-23855/? W/Unity: AndroidJNIHelper.GetSignature: using Byte parameters is obsolete, use SByte parameters instead (Filename: ./Runtime/Export/Debug/Debug.bindings.h Line: 35)

When I use sbyte[] instead of byte[] in my C# code instead, the warning disappears, but the array, contains only zeros, after calling read. I doublechecked, the array content is correct in Java.

My JNI knowledge is a bit rusty, but I think what you try to do is not possible, at least not when using “Call”. The issue is that you can not simply pass objects which live on the .NET side in .NET managed memory to Java since Java has it’s own managed memory. That’s why the JNI helper will actually create a native Java array on the Java side and copy the values over through JNI. Of course that temporary array will be destroyed / freed after the call. However the values will not be copied back into your C# memory.

It’s not clear what you need this for. I only want to remind you that JNI is in general really slow and you should avoid copying large amount of data forth and back. If you want to simply use Call you probably just want to have your java method return a byte array. Unity’s JNI bridge wrapper should be able to handle this. So just create the array on the java side and return it. You will have the overhead on both sides anyways.