J'essaie d'utiliser le Android NDK.
Est-il possible de retourner un tableau (dans mon cas un int[]
) créé en JNI vers Java? Si tel est le cas, veuillez fournir un exemple rapide de la fonction JNI.
-Merci
Si vous avez examiné la documentation et avez encore des questions qui devraient faire partie de votre question initiale. Dans ce cas, la fonction JNI de l'exemple crée un certain nombre de tableaux. Le tableau externe est composé d'un tableau 'Object' créé avec la fonction JNI NewObjectArray()
. Du point de vue de JNI, il s’agit d’un tableau à deux dimensions, un tableau d’objets contenant un certain nombre d’autres tableaux internes.
La boucle for suivante crée les tableaux internes de type int [] à l'aide de la fonction JNI NewIntArray()
. Si vous vouliez simplement renvoyer un tableau dimensionnel à une dimension, la fonction NewIntArray()
est celle que vous utiliseriez pour créer la valeur de retour. Si vous voulez créer un tableau de chaînes à une dimension, utilisez la fonction NewObjectArray()
, mais avec un paramètre différent pour la classe.
Puisque vous voulez renvoyer un tableau int, votre code ressemblera à ceci:
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;
}
si quelqu'un veut savoir comment retourner String [] array:
Code Java
private native String[] data();
exportation native
JNIEXPORT jobjectArray JNICALL Java_example_data() (JNIEnv *, jobject);
code natif
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);
}
depuis le lien: http://www.coderanch.com/t/326467/Java/java/Returning-String-String-array-program-Java
Sur la base de la question posée, cela est déjà expliqué dans la première réponse: comment pouvons-nous passer int [] via jobjectArray. Mais voici un exemple de la façon dont nous pouvons renvoyer un jobjectArray contenant des listes de données. Cela peut être utile dans des situations telles que: lorsque quelqu'un doit renvoyer des données au format 2D pour tracer une ligne avec des points x et y. L'exemple ci-dessous montre comment un jobjectArray peut renvoyer des données sous la forme suivante:
Entrée Java sur le JNI:
Tableau [Arraylist
de x points flottants] [Arraylist
de y points flottants]
Sortie JNI vers Java:jobjectArray
[Arraylist
de x points flottants] [Arraylist
de y points flottants]
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;