Я сейчас работаю над реализацией Манглера на Android.
У меня есть класс Java, который выглядит так:
public class VentriloEventData {
public short type;
public class _pcm {
public int length;
public short send_type;
public int rate;
public byte channels;
};
_pcm pcm;
}
Подпись для моего объекта PCM:
$ javap -s -p VentriloEventData
...
org.mangler.VentriloEventData$_pcm pcm;
Signature: Lorg/mangler/VentriloEventData$_pcm;
Я реализую встроенную функцию JNI с именем getevent, которая будет записывать в поля в экземпляре класса VentriloEventData. Что бы это ни стоило, оно определено и называется в Java следующим образом:
public static native int getevent(VentriloEventData data);
VentriloEventData data = new VentriloEventData();
getevent(data);
И моя JNI-реализация 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;
}
Приведенный выше код отлично работает для записи в поле типа (не обернутое классом _pcm). Когда вызывается getevent, проверяется, что data.type равен 1234 на стороне java:)
Моя проблема в том, что утверждение "pcm! = NULL" не будет выполнено. Обратите внимание, что pcm_field! = NULL, что, вероятно, указывает на то, что подпись в этом поле правильная ... поэтому с моим вызовом GetObjectField должно быть что-то не так. Это выглядит хорошо, хотя, если сравнить его с официальными документами JNI .
Последние 2 часа я ломал голову над этой проблемой, и я немного отчаялся ... надеясь, что в этом мне поможет другая точка зрения.
edit1: Это не будет работать ни с одним вложенным объектом, даже с простым 'Ljava / lang / String;' не удастся.
edit2: и ExceptionOccurred и ExceptionCheck возвращают JNI_FALSE.
edit3: не будет работать и со статическими полями.