passing an array of double in JNI

Posted on 1998-05-12
Last Modified: 2013-11-23
I have this method of class 'class1'

public static void method1(double[] a).

How can I pass an 'double v[6]' in C, by means of JNI?
Please show me a sample code.
Question by:jjescri
  • 2

Expert Comment

ID: 1220931
Java objects are addressed and stored as pointers:

                   struct _jobject;

                   typedef struct _jobject *jobject;

                   typedef jobject jclass;

                   typedef jobject jthrowable;

                   typedef jobject jstring;

                   typedef jobject jarray;

                   typedef jarray jbooleanArray;

                   typedef jarray jbyteArray;

                   typedef jarray jcharArray;

                   typedef jarray jshortArray;

                   typedef jarray jintArray;

                   typedef jarray jlongArray;

                   typedef jarray jfloatArray;

                   typedef jarray jdoubleArray;

                   typedef jarray jobjectArray;

                   You may be wondering what the difference is between jobject and jclass. A class pointer (jclass) is a
                   description or template for a class. It is used to construct a new object (jobject) of that class.

                   The second argument of a native method is of type jobject. This is a pointer to the Java object under which this
                   method is acting. For you C++ programmers, jobject is equivalent to the this pointer. If the native method
                   had been a static function, the second argument would have been of type jclass.

                   All native methods have as their first argument the Java Native Method Interface pointer, which is described in the
                   next section.

                   Java Arrays

                   The first major point to remember when dealing with Java arrays is that arrays are themselves Java objects. Arrays
                   do have their own identifier (jobjectArray), but that is only to aid in readability. A jobjectArray reference
                   can be passed and used by any routine expecting a jobject reference.

                   All Java arrays have a length parameter. The JNI provides the function GetArrayLength() to access any array's

                   jsize GetArrayLength(JNIEnv *env, jarray array);

                   To address the individual members of array objects, the JNI contains two major groups of functions. The group you
                   use depends on the type of data held by the array. The first group allows access to arrays of Java objects or
                   references. The second group allows access to arrays of scalar quantities.

                   In the case of arrays of objects, each array index can be set or retrieved by an interface function:

                   jobject GetObjectArrayElement(JNIEnv *env, jarray array, jsize index);

                   void SetObjectArrayElement(JNIEnv *env, jarray array, jsize index, jobject value);

                   Accessing each index with a function is very inefficient when dealing with a scalar quantity such as integers.
                   Performing matrix calculations is horribly slow. To solve this problem, the JNI provides a set of functions that allow
                   a scalar array to be accessed in the native address space.

                   Each scalar type has functions for manipulating arrays of that type. The following statement gives the calling format:

                   NativeType GetArrayElements(JNIEnv *env, jarray array, jboolean *isCopy);

                   There is no actual function called GetArrayElements(). Instead, there are variants for each scalar type. Table
                   32.3 lists all the flavors of GetArrayElements().

                   The third argument (isCopy), is a boolean set by the VM depending on whether the array was originally stored as a
                   C array. If the data of the Java array is stored contiguously, a pointer to that data is returned and isCopy is set to
                   false. If, however, the internal storage is not contiguous, the VM makes a copy of the actual data and sets
                   isCopy to true. The significance of this flag is that if the flag is false, you know you are manipulating the actual
                   array data. Any changes you make are permanent changes. If, on the other hand, you are working with a copy, your
                   changes can be released without saving.

                   Table 32.3. GetArrayElements() function types.

                                             Native Return Type
                                                              Java Array Type
                                             jboolean *
                                             jbyte *
                                             jchar *
                                             jshort *
                                             jint *
                                             jlong *
                                             jfloat *
                                             jdouble *

                   Releasing the local copy back to the Java object is accomplished with the various versions of
                   ReleaseArrayElements(). This is its calling format:

                   void ReleaseArrayElements(JNIEnv *env, jarray array, NativeType elems, jint mode);

                   Again, the actual function name is specific to each scalar type. Table 32.4 lists the types of release functions. The
                   fourth argument (mode) to ReleaseArrayElements() controls the release mode. It has three possible values: 0
                   Copy back the data and release the local storage

                   JNI_COMMIT Copy back the data but do not release the storage

                       JNI_ABORT Release the storage without copying back the data

                       Obviously, if the local data is not a copy, the mode parameter has no effect.

                   Table 32.4. ReleaseArrayElements() function types.

                                                 Native Return Type
                                                                  Java Array
                                                 jboolean *
                                                 jbyte *
                                                 jchar *
                                                 jshort *
                                                 jint *
                                                 jlong *
                                                 jfloat *
                                                 jdouble *

                       NOTE: If you want to work with scalar array data in an unobtrusive manner, the JNI provides a
                       second set of functions that allow the scalar array members to be copied into local storage allocated
                       and managed by the native method. GetArrayRegion() and SetArrayRegion() operate on a
                       subset of an array and use a locally allocated buffer.

                   Native methods can also create a new Java array. The NewArray() functions perform the work:

                   jarray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass,

                                         jobject initialElement);

                   jarray NewScalarArray(JNIEnv *env, jsize length);

                   Enough theory. It's time to apply what you have learned. You should now have enough knowledge to implement the
                   createVals() and reverseArray() native methods from the Demonstration class. Listing 32.3 shows the
                   completed methods; the code is also located on the CD-ROM that accompanies this book. In this example, the
                   methods manipulate an integer array, so the scalar array functions are used.

                   Listing 32.3. The native methods createVals() and reverseArray().


                    * Class:     Demonstration

                    * Method:    createVals

                    * Signature: (I)[I


                   JNIEXPORT jintArray JNICALL Java_Demonstration_createVals

                     (JNIEnv *env, jobject DemoObj, jint len)


                       jintArray RetArray;

                       int x;

                       jint *localArray;

                       RetArray = env->NewIntArray(len);

                       localArray = env->GetIntArrayElements(RetArray, NULL);

                       for ( x = 0; x < len; x++)

                           localArray[x] = len - x - 1;

                       env->ReleaseIntArrayElements(RetArray, localArray, 0);

                       return RetArray;



                    * Class:     Demonstration

                    * Method:    reverseArray

                    * Signature: ([I)V


                   JNIEXPORT void JNICALL Java_Demonstration_reverseArray

                     (JNIEnv *env, jobject DemoObj, jintArray vals)


                           jint x, temp;

                           jsize len;

                           jboolean isCopy;

                           jint *localArray;

                           len = env->GetArrayLength(vals);

                           localArray = env->GetIntArrayElements(vals, &isCopy);

                           for (x = 0; x < len/2; x++)


                               temp = localArray[x];

                               localArray[x] = localArray[len - x - 1];

                               localArray[len - x - 1] = temp;


                           env->ReleaseIntArrayElements(vals, localArray, 0);


                   createVals() uses NewArray() to allocate the integer array. Because NewArray() creates a proper Java
                   object, local access to the data must be acquired using GetIntArrayElements(). After the array has been
                   initialized, the local elements are released back to the Java VM.

                   Reversing the array is similar to creating it. First, the array's length is determined. After the length is known, the
                   array's contents can be acquired and manipulated as a standard C array. Notice that the isCopy parameter is not
                   required. createVals() passes null instead of a pointer because it doesn't care whether the data is a copy.
                   reverseArray() passes a valid pointer, although it never uses the information. Either technique is valid.

for more info go to

Author Comment

ID: 1220932
Adjusted points to 100

Accepted Solution

evijay earned 100 total points
ID: 1220933
Here is a sample application to do that

import java.util.*;

public class TestDouble
        public native static void printDoubleArray(double[] arr);
        static {
        public static void main(String args[])
                double[] a = { 20.0, 30.0, 22.0 };



#include "TestDouble.h"

JNIEXPORT void JNICALL Java_TestDouble_printDoubleArray
  (JNIEnv *env, jclass myclass, jdoubleArray myarray)
        jsize length;
        jboolean isCopy;
        jdouble *localArray;
        jint i;

        length = (*env)->GetArrayLength(env, myarray);
        localArray = (*env)->GetDoubleArrayElements(env, myarray, &isCopy);
        for (i = 0; i < length; i++)
                printf("%lf\n", localArray[i]);

        (*env)->ReleaseDoubleArrayElements(env, myarray, localArray, 0);


Step 2:
javah TestDouble
cl -Ic:\jdk1.1.4\include -Ic:\jdk1.1.4\include\win32  -LD TestDouble.c -FeTestDouble.dll c:\jdk1

(note: change jdk1.1.4 to appropriate directory)


Featured Post

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Should localization be done inside spring controller 5 26
jboss wildfly 10.1 10 94
Problem to Alipay 10 23
Is there a simpler dropbox system? 10 22
For customizing the look of your lightweight component and making it look opaque like it was made of plastic.  This tip assumes your component to be of rectangular shape and completely opaque.   (CODE)
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Viewers learn about the scanner class in this video and are introduced to receiving user input for their programs. Additionally, objects, conditional statements, and loops are used to help reinforce the concepts. Introduce Scanner class: Importing…
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question