2016-08-11 8 views
0

JNIを使​​用してC++からJAVAにいくつかの値を渡す必要があるという要件があります。要件によると、C++コードへの入力はポイントのリストを持つ行で、各ポ​​イントのx座標とy座標を読み取り、javaコードに戻ります。std :: list> listofpointsとしてリストを宣言しました。 x及びyはこのgeometry.points C++からリストを読み込み、JAVAに戻るJNIラッパー

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)); 

として座標を読み出し、各点のx座標とy座標を取得を読み取ることです。今、このlistofpointsをJNIメソッドに戻しています。ここでは、xとy座標を読み取り、JAVAメソッドに送るようにコードを記述しなければなりません。私はリストを反復して値を取得する方法を探していますが、私はJNIがjobjectarrayだけを返すので、JNIからJAVAに戻ることは難しいと思っています。どのように私はこのリストをJNIの配列に変換し、JAVAメソッドに送ることができますか?私はJNIとJavaにも非常に新しいです。

答えて

3

は、Java List<Pair<Double, Double>>std::list<std::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; 
} 

言った、おそらく上std::vectorを使用する方が簡単ですC++側。 double[]std::pairのコンポーネントを平らにし、および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; 
} 
+0

それは見た目が単純です。私は実装し、その結果をあなたに知らせます。あなたのお返事ありがとうございました。 – kala

+0

本当にうまく働いています。しかし、jdoubleArrayの代わりにjobjectarrayをどのように送ることができるか教えてください。 – kala

+0

@ Kala、 'NewObjectArray'を使う必要があり、' double'を直接入れることはできません。ここをクリックしてください:[JNI関数](http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html) –

関連する問題