usar una restricción métodos metodos metodo los llamar las estáticos estaticos estatico declarados cuando como clase atributos almacenan java c++ static jni

java - una - JNI invocando métodos estáticos. ¿Es el objeto de clase necesario?



public static java (1)

Comencé a usar JNI para invocar métodos java estáticos de C ++. Específicamente, después de obtener un jclass (usando FindClass) y un jmethodID (usando GetStaticMethodID), procedí a llamar a la serie de rutinas CallStatic * MethodA. Resulta que todas estas rutinas toman un jclass como primer parámetro. Comencé a preguntarme por qué se necesita el objeto de clase: dado que toda la información se proporcionó en GetStaticMethodID, el objeto de clase parece innecesario para que la JVM realice el trabajo. Luego intenté llamar a estas rutinas mientras pasaba NULL para el primer parámetro, y la invocación tuvo éxito.

Mi pregunta: ¿Es seguro llamar a estos métodos con un objeto de clase NULL?

El incentivo es: si es legal, no tendré que almacenar en caché el objeto de clase para llamadas posteriores a los métodos estáticos (mientras recuerdo llamar a NewGlobalRef ...). El almacenamiento en caché del jmethodID sería suficiente.


No, no es absolutamente seguro llamar a dicha función estática con un puntero de clase nulo (o inválido).

Su práctica puede tener éxito, por ejemplo, si su método estático no se refiere a ningún otro miembro estático de la clase. Sin embargo, si su método Java estático se refiere a cualquier otro miembro estático, su JVM necesitará el puntero de clase válido.

Ejemplo:

Toma esta simple demo de 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; }

Y llámalo con el siguiente fragmento 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; } }

Llamar a GetStaticMethodID(nullptr, "mymain", "()V"); fallaría. Porque cuando mymain() ejecuta, intentará acceder a la variable estática magic_number . La JVM usará el puntero de clase que ha proporcionado y asumirá que es un puntero de vaild devuelto por una clase cargada. Pero como es nulo, el sistema segfault.