37

This is the first time that I use the JNI and also the first time that I have to write some lines in C.

What I am trying to do is very simple. I'm just trying to switch the endiannes of a byte[] using a C routine.

In java it is done like this:

public void switchEndianness(byte[] array){

        byte byte1;
        byte byte2;

        for(int i = 0; i < array.length ; i+=2){
            byte1 = array[i];
            byte2 = array[i+1];

            array[i] = byte2;
            array[i+1] = byte1;
        }
}

So to do this using JNI, I've tried to imlpement the same routine in the JNICALL, but it doesn't compile. What I've written so far is this:

JNIEXPORT void JNICALL Java_CEndianness_switchEndianness(JNIEnv *env, jobject obj, jbyteArray array, jint offset, jint length){

    char byte1;
    char byte2;

    int i;
    for(i = offset; i  < length ; i+=2){
        byte1 = array[i];
        byte2 = array[i+1];

        array[i] = byte2;
        array[i+1] = byte1;
    }
}

I have no clue how to use the jbyteArray type of data. is it possible to store a jbyte in a char??? Another question is.. when this routine is over...will the byte[] in java be modified?? Or is it only modified inside the C call?

Any help???

Thanks to everybody!

blutech
  • 371
  • 1
  • 3
  • 3

2 Answers2

63

you can get jbyte* by GetByteArrayElements:

jbyte* bufferPtr = (*env)->GetByteArrayElements(env, array, NULL);

And it is important to know the length of your array:

jsize lengthOfArray = (*env)->GetArrayLength(env, array);

Having jbyte* and length, you can do all the things in c-array. Finally, releasing it:

(*env)->ReleaseByteArrayElements(env, array, bufferPtr, 0);
qrtt1
  • 7,746
  • 8
  • 42
  • 62
  • 15
    Note that if possible, it is recommended to use `(*env)->ReleaseByteArrayElements(env, array, bufferPtr, JNI_ABORT);`. The last parameter means that the JVM will not try to copy the bytes back from bufferPtr to the Java array. Very often, you know that the C function will not change the array. – Alex Cohn Nov 23 '13 at 08:43
  • 8
    If you are using C++ instead of C, the syntax is a little different. You don't need to dereference env, and you don't need to pass it as a parameter. For example, bufferPtr = env->GetByteArrayElements(array, NULL). – John Henckel Mar 17 '14 at 14:06
9

qrtt has given you a great answer.

However, the JNI has very comprehensive and (relatively) easy-to-understand documentation that you should read front-to-back if you will be using JNI features again in the future. You can find it here: http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html

For your particular case, here's the section on dealing with arrays: http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/design.html#wp1265

Jason LeBrun
  • 13,037
  • 3
  • 46
  • 42
  • 1
    the url is changed. :) http://docs.oracle.com/javase/1.4.2/docs/guide/jni/spec/jniTOC.html – qrtt1 Mar 10 '13 at 02:42
  • 2
    the url is changed again: http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html – Chris Jan 08 '14 at 15:28
  • 5
    When I was learning JNI, I read the documentation front-to-back. It was quite helpful. – Jason LeBrun Feb 19 '15 at 23:19
  • 4
    Right, but the purpose of StackOverflow is not to point people to documentation. The purpose is to provide answers and include links to documentation as reference. – Krystian Mar 17 '17 at 10:05
  • If you aren't prepared to read the documentation front to back, prepare yourself for many disappointments while using the JNI. – user1725145 Jul 09 '19 at 15:27
  • If you're only prepared to link people to reference docs whose permalinks aren't, prepare _yourself_ to BE that disappointment when using SO. "Even I can't be bothered to look through the often cryptic, indecipherable incantations posted in this unholy codex, but I'll throw you a bone: RTFM*; here's a link that probably once worked." You really can't see how unhelpfully-dismissive that is? I think it's pretty good odds that if someone is asking this community especially (given how know for supportive it is) they DID read it. This is LAST RESORT, for THIS REASON. _*Read the Faustian Manuscript_ – NerdyDeeds Feb 27 '23 at 13:46