2010-03-19 10 views
1

저는 현재 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 : 정적 필드에서도 작동하지 않습니다.

답변

4

그럼 전체 코드라면 pcm이되어야합니다. NULL이되어야합니다. 객체 pcm은 결코 Java 측이나 C++ 측에서 인스턴스화되지 않습니다.

+1

와우, 그건 아주 당황 스럽네. 내 C + + 사고 방식으로 생각했다. '_pcm pcm'은 객체가 스택에 만들어 졌음을 의미합니다. _pcm pcm = new _pcm()이어야합니다. 좋은 웃음을 가지고 300 rep bounty를 즐기십시오;) –

관련 문제