简体   繁体   中英

JNI wrapper to read list from C++ and return to JAVA

I have a requirement where I need to pass some values from C++ to JAVA using JNI. As per the requirement, input to c++ code is a line with list of points and I have to read x and y coordinates of each and every point and return to java code.I have declared a list as std::list> listofpoints; and reading x and y coordinates as

for(size_t j = 0; j < track->geometry.points.size(); ++j)
{

 PointZ &p = track->geometry.points[j]             listofpoints.push_back(std::pair<double, double>(p.vertex.position.x,p.vertex.position.y)); 

This geometry.points is to read each and point gets x and y coordinates. Now I am returning this listofpoints to JNI method. Here I have to write code so that it reads x and y coordinates and send it to JAVA method. I am finding a way to iterate list and get values but , i am finding it difficult to return from JNI to JAVA as JNI returns only jobjectarray. How can i convert this list to array in JNI and send to JAVA method. I am very much new to JNI and JAVA as well.

You can convert the std::list<std::pair<double, double>> to a Java List<Pair<Double, Double>> .

Here is an example:

The Java method:

public static native List<Pair<Double, Double>> getList();

The C++ part:

std::list<std::pair<double, double>> myList{ // example input
    {1, 2},
    {3, 4}
};

JNIEXPORT jobject JNICALL Java_Main_getList(JNIEnv *env, jclass cls) {
    // First, get all the methods we need:
    jclass arrayListClass = env->FindClass("java/util/ArrayList");    
    jmethodID arrayListConstructor = env->GetMethodID(arrayListClass, "<init>", "()V");
    jmethodID addMethod = env->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z");

    jclass pairClass = env->FindClass("javafx/util/Pair");
    jmethodID pairConstructor = env->GetMethodID(pairClass, "<init>", "(Ljava/lang/Object;Ljava/lang/Object;)V");        

    // This is needed to go from double to Double (boxed)
    jclass doubleClass = env->FindClass("java/lang/Double");    
    jmethodID doubleValueOf = env->GetStaticMethodID(doubleClass, "valueOf", "(D)Ljava/lang/Double;");

    // The list we're going to return:
    jobject list = env->NewObject(arrayListClass, arrayListConstructor);

    for(auto& coord : myList) {
        // Convert each C++ double to a java.lang.Double:
        jobject x = env->CallStaticObjectMethod(doubleClass, doubleValueOf, coord.first);
        jobject y = env->CallStaticObjectMethod(doubleClass, doubleValueOf, coord.second);

        // Create a new pair object
        jobject pair = env->NewObject(pairClass, pairConstructor, x, y);
        // Add it to the list
        env->CallBooleanMethod(list, addMethod, pair);
    }

    return list;
}

That said, it is probably easier to use a std::vector on the C++ side. Flatten the components of the std::pair into a double[] , and pass that back to java:

public static native double[] getList();

C++:

std::vector<std::pair<double, double>> myList{ // Now an std::vector
    {1, 2},
    {3, 4}
};

JNIEXPORT jdoubleArray JNICALL Java_Main_getList(JNIEnv *env, jclass cls) {
    size_t length = myList.size() * 2;
    double input[length];

    // Flatten pairs
    for(int i = 0, j = 0; i < length; i += 2, j++) {    
        input[i] = myList[j].first;
        input[i + 1] = myList[j].second;
    }

    // Copy into Java double[]
    jdoubleArray array = env->NewDoubleArray(length);        
    env->SetDoubleArrayRegion(array, 0, length, ((jdouble*) &input));

    return array;
}

Then on the Java side, you would do some further translations. For instance:

public List<Pair<Double, Double>> getTranslated() {
    List<Pair<Double, Double>> ret = new ArrayList<>();

    double[] list = getList(); // Calling our native method
    for(int i = 0; i < list.length; i += 2) {
        ret.add(new Pair<>(list[i], list[i + 1]));
    }

    return ret;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM