2010-03-19 8 views
1

Je travaille actuellement sur l'implémentation Android Mangler's.JNI - GetObjectField renvoie NULL

J'ai une classe java qui ressemble à ceci:

public class VentriloEventData { 
public short type; 
public class _pcm { 
    public int length; 
    public short send_type; 
    public int rate; 
    public byte channels; 
}; 
_pcm pcm; 
} 

La signature de mon objet pcm:

$ javap -s -p VentriloEventData 
... 
org.mangler.VentriloEventData$_pcm pcm; 
    Signature: Lorg/mangler/VentriloEventData$_pcm; 

J'implémenter une fonction JNI native appelée getevent, qui va écrire à la champs dans une instance de la classe VentriloEventData. Pour ce que ça vaut la peine, il est défini et appelé en Java comme ceci:

public static native int getevent(VentriloEventData data); 
VentriloEventData data = new VentriloEventData(); 
getevent(data); 

Et ma mise en œuvre JNI de getevent:

JNIEXPORT jint JNICALL Java_org_mangler_VentriloInterface_getevent(JNIEnv* env, jobject obj, jobject eventdata) { 
v3_event *ev = v3_get_event(V3_BLOCK); 
if(ev != NULL) { 
    jclass event_class = (*env)->GetObjectClass(env, eventdata); 

    // Event type. 
    jfieldID type_field = (*env)->GetFieldID(env, event_class, "type", "S"); 
    (*env)->SetShortField(
    env, 
    eventdata, 
    type_field, 
    1234 
); 

    // Get PCM class. 
    jfieldID pcm_field = (*env)->GetFieldID(env, event_class, "pcm", "Lorg/mangler/VentriloEventData$_pcm;"); 
    jobject pcm = 
    (*env)->GetObjectField(
    env, 
    eventdata, 
    pcm_field 
); 
    jclass pcm_class = (*env)->GetObjectClass(env, pcm); 

    // Set PCM fields. 
    jfieldID pcm_length_field = (*env)->GetFieldID(env, pcm_class, "length", "I"); 
    (*env)->SetIntField(
    env, 
    pcm, 
    pcm_length_field, 
    1337 
); 

    free(ev); 
} 
return 0; 
} 

Le code ci-dessus fonctionne bien pour l'écriture dans le champ de type (ce n'est pas enveloppé par la classe _pcm). Une fois que getevent est appelé, data.type est vérifié comme étant 1234 du côté java :)

Mon problème est que l'assertion "pcm! = NULL" échouera. Notez que pcm_field! = NULL, ce qui indique probablement que la signature de ce champ est correcte ... il doit donc y avoir quelque chose qui ne va pas avec mon appel à GetObjectField. Il semble bien si je le compare à la official JNI docs.

Je me suis moqué de ce problème ces 2 dernières heures et je commence à désespérer ... en espérant qu'un point de vue différent m'aidera sur ce problème.

edit1: Ceci ne fonctionnera pas avec n'importe quel objet imbriqué, même un simple 'Ljava/lang/String;' va échouer.
edit2: ExceptionOccurred et ExceptionCheck renvoient tous deux JNI_FALSE.
edit3: Ne fonctionne pas avec les champs statiques non plus.

Répondre

4

Eh bien, si c'est le code complet, alors je devrais pcmdevrait être NULL. L'objet pcm n'est jamais instancié, ni du côté Java, ni du côté C++.

+1

Oh wow, c'est assez embarassant. Je pensais avec mon état d'esprit C++, où '_pcm pcm' signifie simplement que l'objet est créé sur la pile ... Cela aurait dû être _pcm pcm = new _pcm(). Bon rire et profiter de la générosité de 300 rep;) –