2010-03-19 282 views
1

我目前正在致力於Mangler's Android實施。JNI - GetObjectField返回NULL

我有一個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; 

我實現所謂getevent本地JNI功能,這將會寫入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在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代表賞金;) – 2010-03-22 20:57:34