我目前正在致力于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:无法使用静态字段。
哦哇,这很尴尬。我正在用我的C++思维方式思考,其中“_pcm pcm”只是表示对象是在堆栈上创建的......应该是_pcm pcm = new _pcm()。祝好笑,享受300代表赏金;) – 2010-03-22 20:57:34