Note that there are some explanatory texts on larger screens.

plurals
  1. POCreating a byte[][] in C++ and returning it to Java using JNI
    text
    copied!<p>I have a JNI function, written in C++, that takes a byte array as input, segments it, and returns an array of byte arrays to Java.</p> <p>JNIEXPORT jobjectArray JNICALL Java_class_method(JNIEnv *env, jobject o, jbyteArray dataToSegment);</p> <p>On the Java side, it's something as simple as:</p> <pre><code>byte[] arg = getRandomByteArray(); Object[] retVal = x.method(arg); </code></pre> <p>Now, I'm finding the JNI part to be a bit tricky. I intend to create an array of Objects, each of which is a byte array. This is because JNI only defines a limited number of Java types. There's a jbyteArray type, and a jobjectArray type, but no jarrayOfByteArrays type.</p> <p>So I create my array of Objects, each Object being initialized as a new byte[1024]:</p> <pre><code>jobjectArray retVal = env-&gt;NewObjectArray(numSegs, env-&gt;FindClass("[Ljava/lang/Object;"), env-&gt;NewByteArray(1024)); </code></pre> <p>I then iterate over all the indexes in this array, doing something like:</p> <pre><code>jbyteArray tmp = (jbyteArray) env-&gt;GetObjectArrayElement(retVal, i); env-&gt;SetByteArrayRegion(tmp, 0, size, (jbyte*) sourceBuffer); env-&gt;SetObjectArrayElement(retVal, i, (jobject) tmp); // &lt;--- Questionable line </code></pre> <p>and everything works great, for the most part. However, what if I wanted each byte array to be of variable length? That is, I want the array of byte arrays to be "jagged". What do I pass as the last parameter to NewObjectArray() as the initial value? I've tried passing 0 as the initial value to prevent initialization at time of jobjectArray creation, and then allocating new jbyteArray objects to pass to SetObjectArrayElement(), but this would only end up throwing ArrayStoreException every time I tried to call SetObjectArrayElement. Indeed, even assigning a new jbyteArray to the tmp object (instead of one from GetObjectArrayElement()) results in that same exception being thrown when SetObjectArrayElement() is called. Is there a reason why that last line of code would be an issue? Is it not possible to call SetObjectArrayElement() with a jbyteArray as a parameter?</p> <p>It seems, upon further inspection, that that "Questionable line" isn't doing anything at all. When I comment it out, any changes made to tmp are reflected in retVal. I understand this is because the SetByteArrayRegion call is dealing with the byte array that's "in" the jobjectArray, and not a copy. That would be sufficient for me if all rows (rather, all single-dimensional byte arrays) were the same length. But they're not. How do I assign a new byte array to one of the rows in this object array?</p> <p>TL;DR: With JNI, I have a jobjectArray of jbyteArrays. How do I replace one of the jbyteArrays with a new one that was created with NewByteArray? Hint: env->SetObjectArrayElement(retVal, i, (jobject) env->NewByteArray(size)); // doesn't work.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload