tipo protegida memoria leer intento info excepción escribir controlada catch accessviolationexception java c++ jni

java - protegida - exception info system accessviolationexception



JNI Getting Exception Info-Intentó leer o escribir en la memoria protegida (3)

Estoy usando el siguiente código para tratar de obtener una clase RWException (que amplía Exception) en java para que pueda llamar a un método "getCode ()" para recuperar un código de error (int) y manejar el error correctamente. Revisé los documentos de JNI y creé el siguiente código ... el problema es que recibo una excepción de AccessViolation cuando intento llamar al método sin parámetros getCode (). Obtengo un identificador válido para la clase y el ID de método que estoy buscando.

jstring o = (jstring)envLoc->CallStaticObjectMethod(cls, mid, jstrUser, jstrPass, jstrGroup); jthrowable exc = envLoc->ExceptionOccurred(); if (exc) { // Get the class jclass mvclass = env->GetObjectClass( exc ); // Get method ID for method jmethodID mid = env->GetMethodID(mvclass, "getCode", "()I"); // Call the method jint code = env->CallIntMethod(mvclass, mid); }

Este código me da una excepción al depurar en VS.NET con la siguiente información:

Intento de leer o escribir en la memoria protegida

ACTUALIZAR Aquí está el método java que deseo invocar a través del código JNI arriba:

public int getCode() { return code; }

Ambos objetos, mvclass y mid, se crean correctamente y deben funcionar a menos que me falta algo.

ACTUALIZACIÓN 2

Si ejecuto el siguiente código, el método toString () funciona usando el mismo concepto:

jstring o = (jstring)envLoc->CallStaticObjectMethod(cls, mid, jstrUser, jstrPass, jstrGroup); exc = envLoc->ExceptionOccurred(); if (exc) { envLoc->ExceptionClear(); // Get the class jclass exccls = envLoc->GetObjectClass(exc); // Get method ID for methods jmethodID getCodeMeth = envLoc->GetMethodID(exccls, "getCode", "()I"); jmethodID getMsgMeth = envLoc->GetMethodID(exccls, "toString", "()Ljava/lang/String;"); jstring obj = (jstring)envLoc->CallObjectMethod(exccls, getMsgMeth); String^ toString = JStringToCliString(obj); // this is where the access violation occurs jint jcode = envLoc->CallIntMethod(exccls, getCodeMeth); int code = jcode; }

Entonces, el método toString () devuelve el nombre de clase completo del objeto y es el objeto RWException correcto. El método descrito en la primera actualización getCode () es público, etc. por lo que no estoy seguro de por qué da un error de violación de acceso a la memoria.


El único problema posible que puedo ver en su código es que está llamando a un método mientras una excepción todavía se está propagando. envLoc->ExceptionOccurred() le proporciona el objeto de excepción pero todavía tiene que atraparlo con envLoc->ExceptionClear() .


// exc is the exception object exc = envLoc->ExceptionOccurred(); ... // exccls is the exception CLASS jclass exccls = envLoc->GetObjectClass(exc); jmethodID getCodeMeth = envLoc->GetMethodID(exccls, "getCode", "()I"); ... // CallIntMethod(jobject instance, jmethodID method) jint jcode = envLoc->CallIntMethod(exccls, getCodeMeth); // exccls is the CLASS, not the object // so correct would be: jint jcode = envLoc->CallIntMethod(exc, getCodeMeth);

Oh wow.

Y el compilador no se queja de esto porque cada jclass es un jobject , al igual que jstring .


No tiene errores al verificar en este código. Debe verificar el resultado de cada operación JNI: GetObjectClass (), GetMethodID (), CallXXXMethod () ... Por ejemplo, usted está asumiendo que la clase tiene un método getCode () y lo llama sin verificarlo.