JNI에서 Java로 배열을 반환하는 방법은 무엇입니까?


130

안드로이드 NDK를 사용하려고합니다.

int[]JNI에서 생성 된 배열 (제 경우에는 )을 Java 로 반환하는 방법이 있습니까? 그렇다면,이를 수행하는 JNI 기능의 빠른 예를 제공하십시오.

-감사

답변:


120

문서를 검토 한 후에도 여전히 초기 질문의 일부인 질문이있는 경우 이 경우 예제의 JNI 함수는 여러 배열을 작성합니다. 외부 배열은 JNI 함수로 생성되는 'Object'배열로 구성됩니다 NewObjectArray(). JNI의 관점에서 볼 때, 그것은 2 차원 배열입니다. 다수의 다른 내부 배열을 포함하는 객체 배열입니다.

다음 for 루프는 JNI 함수를 사용하여 int [] 유형의 내부 배열을 작성합니다 NewIntArray(). int의 1 차원 배열을 반환하려면 NewIntArray()함수가 반환 값을 만드는 데 사용하는 것입니다. 문자열의 단일 차원 배열을 만들려면 NewObjectArray()함수를 사용 하지만 클래스에 다른 매개 변수를 사용하십시오.

int 배열을 반환하려고하므로 코드는 다음과 같습니다.

JNIEXPORT jintArray JNICALL Java_ArrayTest_initIntArray(JNIEnv *env, jclass cls, int size)
{
 jintArray result;
 result = (*env)->NewIntArray(env, size);
 if (result == NULL) {
     return NULL; /* out of memory error thrown */
 }
 int i;
 // fill a temp structure to use to populate the java int array
 jint fill[size];
 for (i = 0; i < size; i++) {
     fill[i] = 0; // put whatever logic you want to populate the values here.
 }
 // move from the temp structure to the java structure
 (*env)->SetIntArrayRegion(env, result, 0, size, fill);
 return result;
}

응, 벌써 했어 내 문제 (마지막 예제)와 관련된 예제를 이해하는 데 어려움을 겪고 있었고 누군가 int []를 반환하여 더 간단한 예제를 설명하고 싶을 지 궁금했습니다.
RyanCheu

편집 : 내 이전 의견을 무시하십시오. 위의 코드가 작동합니다. 감사합니다! 매우 도움이되었습니다.
RyanCheu

3
EDIT2 : 코드가 작동하지만 SetIntArrayRegion (...)에서 tmp를 채워야합니다.
RyanCheu

41

누군가 String [] 배열을 반환하는 방법을 알고 싶다면 :

자바 코드

private native String[] data();

기본 수출

JNIEXPORT jobjectArray JNICALL Java_example_data() (JNIEnv *, jobject);

네이티브 코드

  JNIEXPORT jobjectArray JNICALL   
               Java_example_data  
  (JNIEnv *env, jobject jobj){  

    jobjectArray ret;  
    int i;  

    char *message[5]= {"first",   
                       "second",   
                       "third",   
                       "fourth",   
                       "fifth"};  

    ret= (jobjectArray)env->NewObjectArray(5,  
         env->FindClass("java/lang/String"),  
         env->NewStringUTF(""));  

    for(i=0;i<5;i++) {  
        env->SetObjectArrayElement(  
        ret,i,env->NewStringUTF(message[i]));  
    }  
    return(ret);  
  }  

링크에서 : http://www.coderanch.com/t/326467/java/java/Returning-String-array-program-Java


0

묻는 질문을 바탕으로, 이것은 jobjectArray를 통해 int []를 전달할 수있는 첫 번째 답변에서 이미 설명되었습니다. 그러나 다음은 데이터 목록을 포함하는 jobjectArray를 반환하는 방법의 예입니다. 이것은 예를 들어 누군가가 x와 y 포인트로 선을 그리기 위해 2D 형식으로 데이터를 반환해야 할 때 도움이 될 수 있습니다. 아래 예제는 jobjectArray가 다음 형식의 형식으로 데이터를 반환하는 방법을 보여줍니다.

JNI에 대한 Java 입력 : x
[ Arraylist부동 소수점 수] [[ Arraylisty 부동 소수점 수]

Java에 대한 JNI 출력 :
jobjectArray[ Arraylistof x float points] [ Arraylistof y float points]

    extern "C" JNIEXPORT jobjectArray JNICALL
        _MainActivity_callOpenCVFn(
                JNIEnv *env, jobject /* this */,
                jobjectArray list) {

         //Finding arrayList class and float class(2 lists , one x and another is y)
            static jclass arrayListCls = static_cast<jclass>(env->NewGlobalRef(env->FindClass("java/util/ArrayList")));
            jclass floatCls = env->FindClass("java/lang/Float");
         //env initialization of list object and float
            static jmethodID listConstructor = env->GetMethodID(arrayListCls, "<init>", "(I)V");
            jmethodID alGetId  = env->GetMethodID(arrayListCls, "get", "(I)Ljava/lang/Object;");
            jmethodID alSizeId = env->GetMethodID(arrayListCls, "size", "()I");
            static jmethodID addElementToList = env->GetMethodID(arrayListCls, "add", "(Ljava/lang/Object;)Z");

            jmethodID floatConstructor = env->GetMethodID( floatCls, "<init>", "(F)V");
            jmethodID floatId = env->GetMethodID(floatCls,"floatValue", "()F");


        //null check(if null then return)
        if (arrayListCls == nullptr || floatCls == nullptr) {
            return 0;
        }

    //     Get the value of each Float list object in the array
        jsize length = env->GetArrayLength(list);

        //If empty
        if (length < 1) {
            env->DeleteLocalRef(arrayListCls);
            env->DeleteLocalRef(floatCls);
            return 0;
        }

// Creating an output jObjectArray
    jobjectArray outJNIArray = env->NewObjectArray(length, arrayListCls, 0);

        //taking list of X and Y points object at the time of return
        jobject  xPoint,yPoint,xReturnObject,yReturnObject;

            //getting the xList,yList object from the array
            jobject xObjFloatList = env->GetObjectArrayElement(list, 0);
            jobject yObjFloatList = env->GetObjectArrayElement(list, 1);


     // number of elements present in the array object
        int xPointCounts = static_cast<int>(env->CallIntMethod(xObjFloatList, alSizeId));

        static jfloat xReturn, yReturn;
                jobject xReturnArrayList = env->NewObject(arrayListCls,listConstructor,0);
        jobject yReturnArrayList = env->NewObject(arrayListCls,listConstructor,0);

    for (int j = 0; j < xPointCounts; j++) {
            //Getting the x points from the x object list in the array
            xPoint = env->CallObjectMethod(xObjFloatList, alGetId, j);
            //Getting the y points from the y object list in the array
            yPoint = env->CallObjectMethod(yObjFloatList, alGetId, j);

//Returning jobjectArray(Here I am returning the same x and points I am receiving from java side, just to show how to make the returning `jobjectArray`)  

            //float x and y values
            xReturn =static_cast<jfloat >(env->CallFloatMethod(xPoint, floatId,j));
            yReturn =static_cast<jfloat >(env->CallFloatMethod(yPoint, floatId,j));


            xReturnObject = env->NewObject(floatCls,floatConstructor,xReturn);
             yReturnObject = env->NewObject(floatCls,floatConstructor,yReturn);

            env->CallBooleanMethod(xReturnArrayList,addElementToList,xReturnObject);


            env->CallBooleanMethod(yReturnArrayList,addElementToList,yReturnObject);
            env->SetObjectArrayElement(outJNIArray,0,xReturnArrayList);
            env->SetObjectArrayElement(outJNIArray,1,yReturnArrayList);
        __android_log_print(ANDROID_LOG_ERROR, "List of X and Y are saved in the array","%d", 3);

    }

    return outJNIArray;

-6

간단한 해결책은 C의 파일에 배열 데이터를 쓴 다음 Java에서 파일에 액세스하는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.