Próbuję użyć Android NDK.
Czy istnieje sposób na zwrócenie tablicy (w moim przypadku int[]
) utworzonej w JNI do Javy? Jeśli tak, podaj krótki przykład funkcji JNI, która to zrobi.
-Dzięki
źródło
Próbuję użyć Android NDK.
Czy istnieje sposób na zwrócenie tablicy (w moim przypadku int[]
) utworzonej w JNI do Javy? Jeśli tak, podaj krótki przykład funkcji JNI, która to zrobi.
-Dzięki
Jeśli po zapoznaniu się z dokumentacją nadal masz pytania, które powinny stanowić część Twojego początkowego pytania. W tym przypadku funkcja JNI w przykładzie tworzy kilka tablic. Tablica zewnętrzna składa się z tablicy „Object” tworzonej za pomocą funkcji JNI NewObjectArray()
. Z punktu widzenia JNI, to wszystko dwuwymiarowa tablica to tablica obiektów zawierająca szereg innych wewnętrznych tablic.
Poniższa pętla for tworzy wewnętrzne tablice typu int [] przy użyciu funkcji JNI NewIntArray()
. Jeśli chcesz po prostu zwrócić jednowymiarową tablicę liczb całkowitych, to NewIntArray()
funkcja jest tym, czego użyjesz do utworzenia wartości zwracanej. Jeśli chcesz utworzyć jednowymiarową tablicę ciągów, użyłbyś NewObjectArray()
funkcji, ale z innym parametrem dla klasy.
Ponieważ chcesz zwrócić tablicę int, twój kod będzie wyglądał mniej więcej tak:
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;
}
gdyby ktoś chciał wiedzieć, jak zwrócić tablicę String []:
kod java
private native String[] data();
natywny eksport
JNIEXPORT jobjectArray JNICALL Java_example_data() (JNIEnv *, jobject);
kod natywny
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); }
z linku: http://www.coderanch.com/t/326467/java/java/Returning-String-array-program-Java
źródło
Na podstawie zadanego pytania wyjaśniono to już w pierwszej odpowiedzi, w jaki sposób możemy przekazać int [] za pośrednictwem jobjectArray. Ale oto przykład, jak możemy zwrócić jobjectArray, który zawiera listy danych. Może to być pomocne na przykład w sytuacjach, gdy ktoś musi zwrócić dane w formacie 2D, aby narysować linię z punktami x i y. Poniższy przykład pokazuje, jak jobjectArray może zwracać dane w postaci następującego formatu:
Dane wejściowe Java do JNI:
Array [
Arraylist
of x float points] [Arraylist
of y float points]Wyjście JNI do java:
jobjectArray
[Arraylist
z x punktów zmiennoprzecinkowych] [Arraylist
z y punktów zmiennoprzecinkowych]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;
źródło
Prostym rozwiązaniem jest zapisanie danych tablicy w pliku z C, a następnie dostęp do pliku z poziomu Java
źródło