2013-04-02 5 views
3

Pour le code suivant de création d'un tableau int pour java à partir de jni, Pourquoi avons-nous besoin de créer un tableau temp [], pourquoi ne pouvons-nous pas remplir le résultat [] array et le renvoie au java. Est-ce parce que java et jni doivent utiliser un espace mémoire différent donc deux pointeurs différents? Si oui, quel est le but de cela? Mercipourquoi avoir besoin de créer un tableau temporaire pour retourner un tableau de jni à java

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 temp[256]; 
for (i = 0; i < size; i++) { 
    temp[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, temp); 
return result; 
} 

Répondre

2

La raison de cela, est que vous ne pouvez pas modifier les objets directement à partir jinitArray car ils sont des objets Java ne C de.

Dans votre exemple, vous créez un tableau C et le déplacez vers la structure Java. La même approche doit être respectée lorsque vous modifiez le contenu d'un tableau. Vous avez besoin d'un accesseur qui fournira le tableau C's.

Un exemple de modification de tableau à l'aide de JNI.

JNIEXPORT jintArray JNICALL Java_SendArray_loadFile(JNIEnv *env, jobject obj, jintArray input) { 

    // Convert incoming JNI jinitarray to C's native jint[] 
    jint *inputArray = env->GetIntArrayElements(env, input, NULL); // if last param JNI_TRUE, then a copy is returned. 

    if(NULL == inputArray) { 
     return NULL ; 
    } 

    const jsize length = env->GetArrayLength(input); 

    for (int i = 0; i < length; i++) { 
     inputArray[n] = 0; //We can operate on native jinit[] elements. 
    } 

    // Convert the C's native jinit[] int JNI jinitarray 
    env->ReleaseIntArrayElements(env, input, inputArray, 0); // 0 - copy back the content and free the `input` buffer 

    return inputArray; 
} 

La raison de cela est dans tableau Java est un type de référence similaire à la classe. C'est pourquoi vous devez convertir entre le tableau JNI et le tableau natif.

Note: Présentés à propos d'exemple se référer au type int. JNI définit neuf types de tableaux huit pour les types primitifs (booléen, court, char, octet, int, long, float, double) et un autre pour Object.

Référence:

Get< PrimitiveType>ArrayElements Routines

Java Programming Tutorial Java Native Interface

Accessing Java Arrays

+0

dans votre exemple, qu'est-ce que ENV-> GetIntArrayElements (entrée, NULL) exactement le rendement? l'adresse de l'entrée dans la mémoire? Si oui, l'inputArray et l'entrée doivent être exactement le même élément? – henryyao

+0

Il y avait une faute de frappe dans cette méthode mais je l'ai corrigé. Ce qu'il renvoie, est un pointeur vers l'élément de tableau (ou null si échoue). Le 'input', stockez le pointeur sur' inputArray', en utilisant 'GetIntArrayElements', vous pouvez obtenir ce pointeur ou créer une copie en fonction du dernier paramètre (true/false). Ce n'est pas le même pointeur que 'input'. –

Questions connexes