Search code examples
javacjava-native-interface

How do I call multiple data types from GetDirectBufferAddress in JNI?


I get a bytebuffer via the native methods.

The bytebuffer starts with 3 ints, then contains only doubles. The third int tells me the number of doubles that follow.

I am able to read the first three ints.

Why is the code crashing when I try to read the doubles?

Relevant code to get the first three integers:

JNIEXPORT void JNICALL test(JNIEnv *env, jobject bytebuffer)
{
   int * data = (int *)env->GetDirectBufferAddress(bytebuffer);
}

Relevant code to get the remaining doubles:

double * rest = (double *)env->GetDirectBufferAddress(bytebuffer + 12);

Solution

  • In your posted code, you are calling this:

    double * rest = (double *)env->GetDirectBufferAddress(bytebuffer + 12);
    

    This adds 12 to the bytebuffer jobject, which not a number.

    GetDirectBufferAddress() returns an address; since the first 3 int are 4 bytes each, I believe you are correctly adding 12, but you are not adding it in the right place.

    What you probably meant to do is this:

    double * rest = (double *)((char *)env->GetDirectBufferAddress(bytebuffer) + 12);
    

    For your overall code, to get the initial three ints and the remaining doubles, try something similar to this:

    void * address = env->GetDirectBufferAddress(bytebuffer);
    int * firstInt = (int *)address;
    int * secondInt = (int *)address + 1;
    int * doubleCount = (int *)address + 2;
    double * rest = (double *)((char *)address + 3 * sizeof(int));
    
    // you said the third int represents the number of doubles following
    for (int i = 0; i < doubleCount; i++) {
        double d = *rest + i; // or rest[i]
        // do something with the d double
    }