JNI: passing integer array from Java to C

Remaldeep :

Edit: Skip to part 2 for a simpler code.

Part 1: I am working on a project wherein I have to call Java routines from C++.

I use the following code to call the java method. The parameter is a string array from which the first 2 values are used to read a file from the hard drive decode it and return the data. For testing purpose, I am returning a 1D integer array containing only the first image in the file. There are more images in the file with Z depth and time sequence like in a video, ignoring those for now.

    mid = m_pJVMInstance->m_pEnv->GetStaticMethodID(imageJ_cls, "getIntData", "([Ljava/lang/String;)[I");
    if (mid == nullptr)
        cerr << "ERROR: method not found !" << endl;
    else {
        jobjectArray arr = m_pJVMInstance->m_pEnv->NewObjectArray(2,      // constructs java array of 2
            m_pJVMInstance->m_pEnv->FindClass("java/lang/String"),    // Strings
            m_pJVMInstance->m_pEnv->NewStringUTF("str"));   // each initialized with value "str"
        m_pJVMInstance->m_pEnv->SetObjectArrayElement(arr, 0, m_pJVMInstance->m_pEnv->NewStringUTF("D:\Dev_Environment\Test_Files\\"));  // change an element
        m_pJVMInstance->m_pEnv->SetObjectArrayElement(arr, 1, m_pJVMInstance->m_pEnv->NewStringUTF("4D_1ch.lsm"));  // change an element
        jintArray depth = (jintArray)(m_pJVMInstance->m_pEnv->CallStaticIntMethod(imageJ_cls, mid, arr));   // call the method with the arr as argument.

        m_pJVMInstance->m_pEnv->DeleteLocalRef(arr);     // release the object
    }

The method mid is getting the correct function. The Java code does some processing and returns a integer array to C++ for further processing.

The Java code:

public static int[] getIntData(String[] args) {
    int[] test = new int[1];
    test[0] = 1;
    String dir = args[0];
    String name = args[1];
    String id = dir + name;
    ImageProcessorReader ip_reader = new ImageProcessorReader(
            new ChannelSeparator(LociPrefs.makeImageReader()));
    try {
        IJ.showStatus("Examining file " + name);
        ip_reader.setId(id);
        int num = ip_reader.getImageCount();
        int width = ip_reader.getSizeX();
        int height = ip_reader.getSizeY();
        ImageStack stack = new ImageStack(width, height);
        byte[][][] lookupTable = new byte[ip_reader.getSizeC()][][];

        //TODO: Don't know how to handle multiple channels i.e RGb images currently.
        // Adding all the slices into a 2D array and returning those values.
        int[] test_array = new int[width*height];
        int[][][] return_array = new int[height][width][num];
        for (int i=0; i<num; i++) {
            IJ.showStatus("Reading image plane #" + (i + 1) + "/" + num);
            ImageProcessor ip = ip_reader.openProcessors(i)[0];

            // Copying the value to the return array.
            int[][] temp_array = ip.getIntArray();
            for (int h=0; h < height; h++) {
                for (int w = 0; w < width; w++) {
                    return_array[h][w][i] = temp_array[h][w];
                    if (i==0){
                        test_array[h*width + w] = temp_array[h][w];
                    }
                }
            }

            //java.awt.image.BufferedImage awt_Ip =  ip.getBufferedImage();
            //ImageIO.write(awt_Ip, "jpg", new File("D:\\Dev_Environment\\Test_Files\\Test_Folder\\out" + Integer.toString(i) + ".jpg"));

            stack.addSlice("" + (i + 1), ip);
            int channel = ip_reader.getZCTCoords(i)[1];
            lookupTable[channel] = ip_reader.get8BitLookupTable();
        }
        IJ.showStatus("Constructing image");
        ImagePlus imp = new ImagePlus(name, stack);

        // ImagePlus show is leading to java window not responding, maybe it is because this program is not a imageJ plugin but a standalone program.
        //imp.show();

        //ImagePlus colorizedImage = applyLookupTables(r, imp, lookupTable);
        //r.close();
        //colorizedImage.show();
        IJ.showStatus("");
        test[0] = 2;
        return test;
    }
    catch (FormatException exc) {
        IJ.error("Sorry, an error occurred: " + exc.getMessage());
        test[0] = 3;
    }
    catch (IOException exc) {
        IJ.error("Sorry, an error occurred: " + exc.getMessage());
        test[0] = 4;
    }
    return test;
}

For testing only I added a test array of size 1 to check the output in C++. I am getting 0 as a return value in the depth variable.

My question is how do we return an integer array from Java to c++? Is jintArray the right way? Consequently, can I return a 3D array from Java to C++?

Edit Part 2: I did a test with new Java code and same C++ code, except now I am calling "getInDataS" from the java side. Here is the java code:

    public static int[] getIntDataS(String[] args) {
    int[] test = new int[10];
    test[0] = 10;
    test[1] = 10;
    test[2] = 10;
    test[3] = 10;
    test[4] = 10;
    test[5] = 10;
    test[6] = 10;
    test[7] = 10;
    test[8] = 10;
    test[9] = 10;
    return test;
}

I am atleast getting some value in the depth variable but as soon as I try to read the values access violation is thrown. Bothe the lines of code throw the error. Here is the C++ Code:

jintArray depth = (jintArray)(m_pJVMInstance->m_pEnv->CallStaticIntMethod(imageJ_cls, mid, arr));
jsize len = m_pJVMInstance->m_pEnv->GetArrayLength(depth);
jint* body = m_pJVMInstance->m_pEnv->GetIntArrayElements(depth, 0);
Alex Cohn :

Returning int array works exactly as you describe, but the JNI function to call such Java method is not CallStaticIntMethod(), but CallStaticObjectMethod(). This is the most likely cause of the error you get.

To accept a 2D array (or more) in C, you declare it as jobjectArray, and get the object value of each element as jintArray.

Note that your C code leaks some local references, which may be a problem if it is called in a loop. It may be easier to wrap this code with PushLocalFrame() and PopLocalFrame().

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Java

passing string array from java to C with JNI

From Dev

How to pass a Java Integer array into C using JNI?

From Java

Passing strings from java to c++ using JNI

From Dev

Passing float[] from C++ to Java using JNI

From Dev

Passing Integer arguments from Java function to JNI function returning garbage values?

From Dev

C++ error from passing an integer array as a parameter

From Java

Passing a pointer from JNI to Java using a long

From Java

Passing pointers between C and Java through JNI

From Java

JNI: From C code to Java and JNI

From Java

Copying Data from Java to C++ Objects Array Using JNI

From Dev

Get an Array of Strings from Java to C++ JNI

From Dev

Efficiently passing GPB serialized data from Java to C++ using JNI

From Java

Passing double-byte (WCHAR) strings from C++ to Java via JNI

From Dev

passing Integer or String array as an argument in java

From Dev

C++ Passing an array of objects followed by an integer

From Java

Passing Java ArryList<String> to JNI C function and print the list in C

From Dev

Passing Integer List from Java to Oracle Function

From Java

Getting a null byte array in java from JNI

From Java

How to return an array from JNI to Java?

From Java

How to return int array from Java to JNI

From Dev

Passing array from Java to VBScript

From Java

Return a 2D primitive array from C to Java from JNI/NDK

From Java

Java JNI - Is it possible to set an individual primitive array element in Java from C++

From Java

In JNI, can you pass a C integer parameter to a Java primitive int?

From Dev

issue passing mat from java to c++ jni android arm64-v8a 32/64 bit

From Dev

JNI Pass a String from java to c++ and then pass c++ string to string Array

From Dev

JNI conversion from Java to C++

From Dev

How to pass byte array from android java class to JNI C NDK?

From Dev

How to pass char array from C JNI function to Java method as byte[]

Related Related

  1. 1

    passing string array from java to C with JNI

  2. 2

    How to pass a Java Integer array into C using JNI?

  3. 3

    Passing strings from java to c++ using JNI

  4. 4

    Passing float[] from C++ to Java using JNI

  5. 5

    Passing Integer arguments from Java function to JNI function returning garbage values?

  6. 6

    C++ error from passing an integer array as a parameter

  7. 7

    Passing a pointer from JNI to Java using a long

  8. 8

    Passing pointers between C and Java through JNI

  9. 9

    JNI: From C code to Java and JNI

  10. 10

    Copying Data from Java to C++ Objects Array Using JNI

  11. 11

    Get an Array of Strings from Java to C++ JNI

  12. 12

    Efficiently passing GPB serialized data from Java to C++ using JNI

  13. 13

    Passing double-byte (WCHAR) strings from C++ to Java via JNI

  14. 14

    passing Integer or String array as an argument in java

  15. 15

    C++ Passing an array of objects followed by an integer

  16. 16

    Passing Java ArryList<String> to JNI C function and print the list in C

  17. 17

    Passing Integer List from Java to Oracle Function

  18. 18

    Getting a null byte array in java from JNI

  19. 19

    How to return an array from JNI to Java?

  20. 20

    How to return int array from Java to JNI

  21. 21

    Passing array from Java to VBScript

  22. 22

    Return a 2D primitive array from C to Java from JNI/NDK

  23. 23

    Java JNI - Is it possible to set an individual primitive array element in Java from C++

  24. 24

    In JNI, can you pass a C integer parameter to a Java primitive int?

  25. 25

    issue passing mat from java to c++ jni android arm64-v8a 32/64 bit

  26. 26

    JNI Pass a String from java to c++ and then pass c++ string to string Array

  27. 27

    JNI conversion from Java to C++

  28. 28

    How to pass byte array from android java class to JNI C NDK?

  29. 29

    How to pass char array from C JNI function to Java method as byte[]

HotTag

Archive