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.
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;) –