我有一个要求,我需要使用JNI将一些值从C ++传递给JAVA。根据要求,输入到c ++代码是一个包含点列表的行,我必须读取每个点的x和y坐标并返回到java代码。我已将列表声明为std :: list> listofpoints;并将x和y坐标读为
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));
这个geometry.points是读取每个和点得到x和y坐标。现在我将这个listofpoints返回给JNI方法。在这里,我必须编写代码,以便读取x和y坐标并将其发送到JAVA方法。我正在寻找一种迭代列表并获取值的方法但是,我发现很难从JNI返回到JAVA,因为JNI只返回jobjectarray。如何将此列表转换为JNI中的数组并发送到JAVA方法。我对JNI和JAVA也很陌生。
答案 0 :(得分:4)
您可以将std::list<std::pair<double, double>>
转换为Java List<Pair<Double, Double>>
。
以下是一个例子:
Java方法:
public static native List<Pair<Double, Double>> getList();
C ++部分:
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;
}
也就是说,在C ++端使用std::vector
可能更容易。将std::pair
的组件展平为double[]
,并将其传递回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;
}
然后在Java方面,你会做一些进一步的翻译。例如:
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;
}