Returning jbyteArray from native c in Android

37,229

use SetByteArrayRegion

charCnt=fread(data, 1, size, fin);

jbyteArray result=(*env)->NewByteArray(env, size);

(*env)->SetByteArrayRegion(env, result, 0, size, data);



one could also use GetByteArrayElements eg:

jboolean isCopy;
jbyte* rawjBytes = (*env)->GetByteArrayElements(env, result, &isCopy);

//do stuff to raw bytes
memcpy(rawjBytes, data, size*sizeof(jbyte));

(*env)->ReleaseByteArrayElements(env, result, rawjBytes, 0);

see here for more details on SetByteArrayRegion, GetByteArrayElements and ReleaseByteArrayElements.


NB: this question is probably a special case of this question

Share:
37,229
Raneez Ahmed
Author by

Raneez Ahmed

Raneesh is a passionate software programmer, who is strongly interested in mobile technology. He completed B.E in Computer Science under Anna University and is a NIIT Certified Java Programmer as well. He started his career as an android developer and is now exploring iOS application development using Swift language. He has sound knowledge in Android application development, and has accomplished experience with business requirements gathering/analysis and implementation for projects. Here he got a hands on experience of integrating applications with Cloud Services , Web services , Audio processing and developing native applications using C, JNI and NDK.

Updated on March 03, 2020

Comments

  • Raneez Ahmed
    Raneez Ahmed about 4 years

    I use native c to read data from an audio file to jbyte pointer. Now i want to send it to java as an jbyteArray.

    jbyteArray Java_com_app_audio_player_readData(JNIEnv * env, jobject jobj,jstring readPath)
    {
    
    FILE *fin;
    const char *inFile= (*env)->GetStringUTFChars(env,readPath,0);
    fin = fopen(inFile, "r");
    
    fseek(fin, 0, SEEK_END); // seek to end of file
     int size = ftell(fin); // get current file pointer
    fseek(fin, 0, SEEK_SET);
    
    jbyte *data=(jbyte *)malloc(size*sizeof(jbyte));
    int charCnt = 0;
    
    charCnt=fread(data, 1, size, fin);
    
    
    jbyteArray result=(*env)->NewByteArray(env, size);
    
         //-- I want to convert data to jbyteArray and return it to java    
    
    fclose(fin);
     return result;
    
    }
    

    How it is done?

  • violet313
    violet313 almost 11 years
    @Roman ~but the intention here is to use memcpy to copy data into rawjBytes?! & demonstrates an alternative to SetByteArrayRegion where lets say, large data needs to be constructed dynamically/incrementally: we can use GetByteArrayElements to gain access to the jbyteArray contents; then calling ReleaseByteArrayElements with zero-valued 3rd arg ensures data is copied back (whether-or-not the underlying memory is pinned).
  • Roman Truba
    Roman Truba almost 11 years
    Ow... I'm sorry, I don't get it. Thank you very much anyway, it's helped me lot.
  • violet313
    violet313 almost 11 years
    @Roman ~ no problemo. & of course one could do what you're suggesting: gain access to the rawjBytes and memcpy them into some other memory location. so i appreciate the potential for confusion &&so it's good you pointed it out :)
  • Trent Gray-Donald
    Trent Gray-Donald over 10 years
    In your SetByteArrayRegion() example, I think you're using "jbyteArray" in the args list when you mean to use "result", right? (ie: use the var name, not its type)
  • violet313
    violet313 about 10 years
    @Trent Gray-Donald +1 ~blinking! imagine failing to notice that before.lol. ~fixed.