java代码:
public class Foo {
private long i = 0;
void printI() {
nativePrintI();
}
private native static void nativePrintI();
}
JNI代码:
JNIEXPORT void JNICALL Java_com_aliyun_livestream_Publisher_nativeRelease
(JNIEnv *env, jobject obj) {
jclass cls = env->GetObjectClass(obj);;
jfieldID iField = env->GetFieldID(cls, "i", "J");
jlong i = env->GetLongField(obj, iField);
printf("%lld\n", i);
}
我的被叫者是这样的:
Foo foo = new Foo();
foo.printI();
有时它运行正常,但有时它失败了消息"" jni对类java.lang.Class"
的对象无效答案 0 :(得分:5)
当您将native
方法声明为static
时,相应的JNI函数将收到JNIEnv*
和jclass
,以及您指定的任何其他参数(在此案例无)。 jclass
参数是对调用该方法的类的引用
这与您在Java中进行的调用没有什么不同;当你调用static
方法时,它将在类上调用,而不是从该类实例化的对象。
另一方面,非静态native
方法将使用JNIEnv*
和jobject
调用JNI函数,其中jobject
是对象的引用在哪个方法被调用。
在C / C ++中,jobject
和jclass
都是指针,因此您可以将一个指定给另一个,但是当您尝试将它们传递给Java时/ JNI函数这些指针指向的底层值是多少
GetObjectClass
和GetLongField
期望您将jobject
传递给他们,因此jclass
案例中的static
将无效。
如果需要jobject
,请在Java中将该方法声明为非静态方法。如果需要jclass
,请在Java中将该方法声明为static。如果您想要两者,请将其声明为非静态,以便您收到jobject
,然后您可以在其上调用GetObjectClass
。
答案 1 :(得分:1)
使用Can I know the name of the class that calls a JNI C method?
中的摘录jclass cls = env->GetObjectClass(obj);
// First get the class object
jmethodID mid = env->GetMethodID(cls, "getClass", "()Ljava/lang/Class;");
jobject clsObj = env->CallObjectMethod(obj, mid);
// Now get the class object's class descriptor
cls = env->GetObjectClass(clsObj);
// Find the getName() method on the class object
mid = env->GetMethodID(cls, "getName", "()Ljava/lang/String;");
// Call the getName() to get a jstring object back
jstring strObj = (jstring)env->CallObjectMethod(clsObj, mid);
// Now get the c string from the java jstring object
const char* str = env->GetStringUTFChars(strObj, NULL);
// Print the class name
printf("\nCalling class is: %s\n", str);
// Release the memory pinned char array
env->ReleaseStringUTFChars(strObj, str);
事实证明,当Calling类名称为" java.lang.Class"时,GetLongField
失败。但是,当呼叫类名称为" Foo"时,GetLongField
成功。
可能是由于Java的GC机制。因为函数nativePrintI
被定义为静态函数。 Java有时会在没有有效实例的情况下调用它。
所以将nativePrintI
更改为private native void nativePrintI();
可以解决问题。