开始使用 JNI 从 C++ 调用静态 java 方法。具体来说,在获得 jclass(使用 FindClass)和 jmethodID(使用 GetStaticMethodID)之后,我继续调用 CallStatic*MethodA 例程系列。事实证明,所有这些例程都将 jclass 作为第一个参数。我开始想知道为什么需要类对象:因为所有信息都在 GetStaticMethodID 中提供,类对象对于 JVM 完成工作似乎是不必要的。然后我尝试调用这些例程,同时为第一个参数传递 NULL,调用成功。
我的问题:使用 NULL 类对象调用这些方法是否安全?
动机是:如果确实合法,我将不必为后续调用静态方法缓存类对象(同时记住调用 NewGlobalRef....)。缓存 jmethodID 就足够了。
最佳答案
不,使用空(或无效)类指针调用此类静态函数绝对不安全。
您的实践可能会非常成功,例如,如果您的静态方法没有引用任何其他静态类成员。但是,如果您的静态 java 方法引用任何其他静态成员,则您的 JVM 将需要有效的类指针。
示例:
以这个简单的 Java 演示 MyTest.java
为例:
public class MyTest {
public static void mymain() {
System.out.println("Hello, World in java from mymain");
System.out.println(magic_counter); // this will cause a segfault if
} // class pointer is null
private static int magic_counter=777;
}
并使用以下 JNI C++ 片段调用它
... // JVM already loaded and initialised
jclass cls2 = env->FindClass("MyTest");
if(cls2 == nullptr) {
cerr << "ERROR: class not found !";
}
else {
cout << "Class MyTest found" << endl;
jmethodID mid = env->GetStaticMethodID(cls2, "mymain", "()V");
if(mid == nullptr)
cerr << "ERROR: method void mymain() not found !" << endl;
else {
env->CallStaticVoidMethod(cls2, mid);
cout << endl;
}
}
调用 GetStaticMethodID(nullptr, "mymain", "()V");
会失败。因为当 mymain()
执行时,它会尝试访问静态变量 magic_number
。然后,JVM 将使用您提供的类指针,并假定它是由加载的类返回的有效指针。但由于它为空,系统将出现段错误。
关于java - JNI 调用静态方法。类对象是必需的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29831703/