JNI - GetObjectField возвращает NULL - PullRequest
2 голосов
/ 19 марта 2010

Я сейчас работаю над реализацией Манглера на 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: не будет работать и со статическими полями.

1 Ответ

6 голосов
/ 22 марта 2010

Ну, если это полный код, тогда я думаю pcm должно быть NULLОбъект pcm никогда не создается, ни на стороне Java, ни на стороне C ++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...