Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting a null byte array in java from JNI

I am calling a native function from java to return a byte[].
The following is a snippet of the JNI code

jbyteArray result;  
jbyte *resultType;  
result = (*env)->NewByteArray(env, 1);  
*resultType =7;
(*env)->SetByteArrayRegion(env, result, 0, 1, resultType);    
return result;

This is supposed to create a byte array of length 1 and the value 7 is stored in it. My actual code is supposed to create an array of dynamic length, but am getting the same problem as in this example.

Now coming to my problem -- in java the array am getting returned from JNI is null. What am I doing wrong? Any help will be appreciated.

like image 696
bobby Avatar asked Apr 27 '11 12:04

bobby


1 Answers

The prototype for SetByteArrayRegion() is:

void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf);

The final argument is a memory buffer which SetByteArrayRegion() will copy from into the Java array.

You never initialize that buffer. You are doing:

jbyte* resultType;
*resultType = 7; 

I'm surprised you don't get a core dump, as you're writing a 7 into some random place in memory. Instead, do this:

jbyte theValue;
theValue = 7;
(*env)->SetByteArrayRegion(env, result, 0, 1, &theValue);

More generally,

// Have the buffer on the stack, will go away
// automatically when the enclosing scope ends
jbyte resultBuffer[THE_SIZE];
fillTheBuffer(resultBuffer);
(*env)->SetByteArrayRegion(env, result, 0, THE_SIZE, resultBuffer);

or

// Have the buffer on the stack, need to
// make sure to deallocate it when you're
// done with it.
jbyte* resultBuffer = new jbyte[THE_SIZE];
fillTheBuffer(resultBuffer);
(*env)->SetByteArrayRegion(env, result, 0, THE_SIZE, resultBuffer);
delete [] resultBuffer;
like image 128
QuantumMechanic Avatar answered Sep 18 '22 03:09

QuantumMechanic