저는 현재 Mangler's Android 구현 중입니다.JNI - GetObjectField가 NULL을 반환합니다.
나는 같은 보이는 자바 클래스가 :
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;
내가 getevent라는 기본 JNI 기능을 구현하고는 쓸 것 필드는 VentriloEventData 클래스의 인스턴스에 있습니다. 그것은 가치가 무엇인지, 그것과 같이 자바에서 정의라고 들어 :
public static native int getevent(VentriloEventData data);
VentriloEventData data = new VentriloEventData();
getevent(data);
그리고 getevent 내 JNI 구현 :
은 위의 코드는 (유형 필드에 쓰기 위해 잘 작동
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은 Java 측에서 1234로 확인됩니다.
"pcm! = NULL"이라는 어설 션이 실패합니다. pcm_field! = NULL은 아마도 해당 필드의 서명이 정확하다는 것을 나타냅니다. 따라서 GetObjectField에 대한 호출이 잘못되어 있어야합니다. 내가 official JNI docs과 비교해도 괜찮아 보입니다.
지난 2 시간 동안이 문제에 대한 내 머리를 깨뜨리고 조금 절박 해졌습니다. 다른 시각을 원하면이 문제를 해결할 수 있기를 바랍니다.
edit1 : 이것은 중첩 된 객체, 심지어 간단한 'Ljava/lang/String;'에서도 작동하지 않습니다. 실패 할 것이다.
edit2 : ExceptionOccurred와 ExceptionCheck 모두 JNI_FALSE를 반환합니다.
edit3 : 정적 필드에서도 작동하지 않습니다.
와우, 그건 아주 당황 스럽네. 내 C + + 사고 방식으로 생각했다. '_pcm pcm'은 객체가 스택에 만들어 졌음을 의미합니다. _pcm pcm = new _pcm()이어야합니다. 좋은 웃음을 가지고 300 rep bounty를 즐기십시오;) –