java - JNI 调用静态方法。类对象是必需的吗?

标签 java c++ static java-native-interface

开始使用 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/

相关文章:

c++ - 用于读取文本文件 C++ 的标准循环

c - 错误 C4700 : uninitialized local variable "" used

swift - 可以在不使用 'Static' 的情况下创建单例类吗?

java - 如何使用 setMaxResults 更新 hibernate 查询?

Java 不同的可用堆大小

java - 为我的游戏添加生命

c++ - 使用静态 SFML 库时无法链接我的项目

c++ - 在 C++ 中用逗号格式化数字

java - 在 Java 中,这些方法中哪种更好?

Java 正则表达式查找除 B 之外的所有 A