Closed malluce closed 3 months ago
I tried the following approach, but the csharpresult
does not contain what i expect the method to return.
IntPtr resultPtr = result.GetUnsafeIntPtr();
JArrayLocalRef arrOutput = arrDel(jEnv, 256); // arrDel is NewByteArrayDelegate
setRegionDel(jEnv, arrOutput, 0, 256, resultPtr); // setRegionDel is SetByteArrayRegionDelegate
IntPtr resultArrayPtr = getBytesDel(jEnv, arrOutput, new JBooleanRef(false)); // getBytesDel is GetByteArrayElementsDelegate
byte[] csharpresult = new byte[256];
Marshal.Copy(resultArrayPtr, csharpresult , 0, 256);
My fix was to change the delegate
internal delegate IntPtr GetByteArrayElementsDelegate(JEnvRef env, JObjectLocalRef jArray, JBooleanRef isCopy);
//internal delegate IntPtr GetByteArrayElementsDelegate(JEnvRef env, JArrayLocalRef jArray, JBooleanRef isCopy);
This way the result can be simply passed in the getByte delegate and the array can be accessed (e.g., via Marshal.Copy). The problem i see here with the library is that JArrayLocalRef and JObjectLocalRef are not type-compatible even though jarray is-a jobject according to the JNI spec (https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/types.html)
To pass a [B to a java method, one must create a JByteArray with JNI, fill it with the desired data, place its JNI reference in a jvalue array, and then pass it to the java method using JNI.
To retrieve the result, again, the method return is a JNI reference, so you need to get elements or region and then once you have a pointer to the data, copy it from Java memory to .NET memory.
JNI reference are no pointers!
Be careful, .GetUnsafeIntPtr() is dangerous; in fact, if you're using an array, you could use GetFixedContext(). The purpose of GetUnsafeIntPtr() is to use memory that is already pinned as stack references.
I'm working in a real JNI .NET solution, in the building branch now Arrays are View objects, so Casting is easier than the main branch.
Hi, I'm using your library to call a Java method with signature "([B)[B". That is, the return type is a byte array.
For this, I use CallObjectMethodADelegate and pass a pointer to my input array.
JObjectLocalRef result = callObjectMethod(jEnv, jObj, jMethodId, arrInput.GetUnsafeIntPtr());
I'm now stuck at processing the return type. I want to transform the result somehow to a C# byte array. Other JNI libraries directly support jbytearray, which would allow casting the jobject to jbytearray and then go from there. However, this seems not possible here.
I'm looking forward to your answers!
Greetings, Felix