I already posted a question regarding it, but at that time I haven't have the account. I got a reply but I was still confused and I cannot continue on that thread.
I am re posting the question again along with a link to previous conversation.
Returning char array from java to string - JNI
The data I am storing in Java is serialized. I make a java function call using following piece of code.
The following code assumes that char of C is compatible with byte of Java, because char of Java is of 2 bytes whereas char of C is of 1 byte. The jbyte is also a signed char*
//value will be the serialized data
void store(char* key, char* value, int val_len)
{
//consider the jclass and methodid are already initialized
jstring j_key = (*env)->NewStringUTF(env, key);
jbyteArray j_value = (*env)->NewByteArray(env, val_len);
(*env)->SetByteArrayRegion(env, j_value, 0, val_len, (jbyte *)value);
//The store method on java side will save the value (as is) in memory
(*env)->CallStaticVoidMethod(j_class, store_method, key, value);
(*env)->ReleaseByteArrayElements(env, j_value, (jbyte *)value, JNI_ABORT);
(*env)->ReleaseStringUTFChars(env, j_key, key);
}
Once I have saved the data, I use another function to retrieve data from store. At that time i do not know the size of data I am going to retrieve. My API is in C and store is in Java. I will use my C functions to interact with Java. And also there can be multiple threads retrieving data from Java store at same time.
I am making calls from C to Java and my control should return to C program after retrieving data. I am a little confuse on how the code will work. How will I get pointer to array (retrieved from java) and then retrieve it using GetByteArrayElements. Remember I dont know the size of data I am going to retrieve before hand and therefore cannot create a byte array using NewByteArray function and later fill it with data in java code.
Ok, I figuered it out. I'll put it down here so others can also take advantage of it.
Consider the following java method that returns a byte array (just a dummy code, no checks etc)
public static byte[] GetData(){
return myStore.getData();
}
and on C side, you can retrieve the byte[] as following
void get_data()
{
int len = 0;
char* value = NULL;
/*Consider j_class, and j_methodid are already initialized*/
jbyteArray j_value = (*env)->CallStaticObjectMethod(env, j_class, j_methodid);
if(j_value != NULL)
{
len = (*env)->GetArrayLength(env, j_value);
value = (*env)->GetByteArrayElements(env, j_value, NULL);
}
/*later on release the resource*/
(*env)->ReleaseByteArrayElements(env, j_value, value, 0);
}
I have checked it and it works. I am going to check it for 2-D array now. I think it'd be the same as this only you'd be getting jobjectArray and every element of this array is a jbyteArray.
Thank you very much! I was trying to pass a double array from C to Java and java in turn returns a renewed double array to C. This is part of JNI where I am trying to link a Java code to Fortran source code. But Fortran code has to call one more Java code for some calculation. So I am doing Java to C to Fortran to C to Java using JNI. Solution to sending a double array from C to Java and Java returning a double array to C is here.
jdoubleArray tempA = (jdoubleArray)(*envG)->NewDoubleArray(envG,3); //create an array with 3 elements to be sent to Java
jdoubleArray tempB = (jdoubleArray)(*envG)->NewDoubleArray(envG,3); //This is will be //assigned to returned java double array
(*envG)->SetDoubleArrayRegion(envG,tempA,0,3,(const jdouble *)arr);//need to send the //tempA array to Java. "arr" is the double array coming to C from Fortran!
int leng = 0;
for (i = 0; i < 1; i++) {
//sending an array "tempA" to Java. Java returns tempB, a double array
tempB = (*envG)->CallObjectMethod(envG, obj_print, id_print,(*A),(*B),(*C),tempA);
if (tempB != NULL){
for (k = 0; k < 3; k++){
leng = (*envG)->GetArrayLength(envG, tempB);
jdouble* value = (*envG)->GetDoubleArrayElements(envG, tempB, NULL);
printf("FROM JAVA ARRAY %f\n", value[k]);
} //end for
} //end if
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With