首页 文章

JNI调用静态方法 . 类对象是否必要?

提问于
浏览
7

开始使用JNI从C调用静态java方法 . 具体来说,在获得jclass(使用FindClass)和jmethodID(使用GetStaticMethodID)之后,我继续调用CallStatic * MethodA例程系列 . 事实证明,所有这些例程都将jclass作为第一个参数 . 我开始想知道为什么需要类对象:因为所有信息都是在GetStaticMethodID中提供的,所以JVM无需使用类对象来完成工作 . 然后,我尝试在为第一个参数传递NULL时调用这些例程,并且调用成功 .

我的问题:使用NULL类对象调用这些方法是否安全?

激励是:如果它确实合法,我将不必为后续调用静态方法缓存类对象(同时记住调用NewGlobalRef ....) . 缓存jmethodID就足够了 .

1 回答

  • 2

    不,使用null(或无效)类指针调用此类静态函数是 absolutely NOT safe .

    您的练习可能非常成功,例如,如果您的静态方法不引用任何其他静态类成员 . 但是,如果静态java方法引用任何其他静态成员,则JVM将需要有效的类指针 .

    Example:

    采取这个简单的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将使用您提供的类指针,并假设它是由加载的类返回的虚拟指针 . 但是因为它是null,系统将是段错误的 .

相关问题