Search code examples
javac++carraysjava-native-interface

Can a Java array be passed to a C/C++ function which takes an array?


I am learning about JNI nowadays. Let us say I have a C/C++ library function, which takes int* array as an input (We assume int is of 4 bytes and signed just like as it is in Java), that is, an array passed as a pointer. Would it be possible to pass a Java array of int to such function through JNI, without doing any copying (Obviously we remove the length part of the Java array while doing so)? Is the direct ByteBuffer the only viable method for doing such things?


Solution

  • A direct ByteBuffer would be one way of avoiding copying, as you mention yourself.

    If you pass a Java array you will need to call Get<Primitive>ArrayElements, which may or may not copy (or Get<Primitive>ArrayRegion, but that would make no sense since it always copies).

    There's also GetPrimitiveArrayCritical which you can use if you only need access to the elements for a "short" amount of time, and don't need to perform any other JNI calls before releasing the elements. It is "more likely" than Get<Primitive>ArrayElements to not copy.

    An example:

    jint len = env->GetArrayLength(myIntArray);
    jint *elements = env->GetPrimitiveArrayCritical(myIntArray, NULL);
    
    // Use elements...
    
    env->ReleasePrimitiveArrayCritical(myIntArray, elements, 0);  
    

    See Oracle's JNI documentation.