title: Passing byte array from native code to the Java side
body: <p>My goal is passing a byte array of variable length from native code to Java side. The Java class instance method takes bytearray as its argument:</p>
  
  <pre><code>private void writeBuffer(final byte[] buffer)
  {
  }
  </code></pre>
  
  <p>I am able to find a method ID in the native code:</p>
  
  <pre><code>jclass cls = (*env)-&gt;FindClass(env,"class_path");
  jmethodID writeBufferMethodID = (*env)-&gt;GetMethodID(env, cls, "writeBuffer", "([B)V");
  </code></pre>
  
  <p>But still can't figure out how to pass a byte array properly. I have tried:</p>
  
  <pre><code>jbyteArray retArray = (*env)-&gt;NewByteArray(env, data_size);
  void *temp = (*env)-&gt;GetPrimitiveArrayCritical(env, (jarray)retArray, 0);
  memcpy(temp, decoded_frame-&gt;data[0], data_size);
  (*env)-&gt;CallVoidMethod(env, obj, writeBufferMethodID, retArray);
  (*env)-&gt;ReleasePrimitiveArrayCritical(env, retArray, temp, 0);
  </code></pre>
  
  <p>and also:</p>
  
  <pre><code>retArray = (*env)-&gt;NewByteArray(env, data_size);
  (*env)-&gt;SetByteArrayRegion(env, retArray, 0, data_size, (jbyte *)decoded_frame-&gt;data[0]);
  (*env)-&gt;CallVoidMethod(env, obj, writeBufferMethodID, retArray);
  </code></pre>
  
  <p>The Java method gets called, but after a while the application crashes. Moreover, all values in Java buffers I receive equal to zero so it seems the content is not copied at all. </p>
  
  <p>I verified the buffers content (decoded_frame->data[0]) on the native side by writing them into the binary file and there is no problem, the file contains exactly what I expect.</p>
  
  <p>I call that method periodically; the size of array can <strong>vary</strong> in <strong>each</strong> call. </p>
  
  <p>What is the correct and most <strong>effective</strong> way? Allocating a new array during each call is obviously a silly idea, but I do not know, how to avoid that if the array size varies.</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>I have rewritten my code this way and it seems to be OK now. </p>
  
  <p>called in a while loop:</p>
  
  <p>...do some decoding...  </p>
  
  <pre><code>if(!retArray)
  retArray = (*env)-&gt;NewByteArray(env, data_size);
  
  if((*env)-&gt;GetArrayLength(env, retArray) != data_size)
  {
  (*env)-&gt;DeleteLocalRef(env, retArray);
  retArray = (*env)-&gt;NewByteArray(env, data_size);
  }
  
  void *temp = (*env)-&gt;GetPrimitiveArrayCritical(env, (jarray)retArray, 0);
  memcpy(temp, decoded_frame-&gt;data[0], data_size);
  (*env)-&gt;CallVoidMethod(env, obj, writeBufferMethodID, retArray);
  (*env)-&gt;ReleasePrimitiveArrayCritical(env, retArray, temp, 0);
  </code></pre>
  
  <p>called at loop exit:</p>
  
  <pre><code>(*env)-&gt;DeleteLocalRef(env, retArray);
  </code></pre>