JNI — Информация об исключении получения JNI — Попытка чтения или записи в защищенную память

Я использую следующий код, чтобы попытаться получить класс RWException (который расширяет Exception) в Java, чтобы я мог вызвать метод «getCode ()», чтобы получить код ошибки (int) и правильно обработать ошибку. Я просмотрел документы JNI и создал следующий код … проблема в том, что я получаю исключение AccessViolation, когда пытаюсь вызвать метод getCode () без параметров. Я получил правильный дескриптор для класса и идентификатор метода, который я ищу.

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);
}

Этот код дает мне исключение при отладке в VS.NET со следующей информацией:

Попытка чтения или записи в защищенную память

ОБНОВИТЬ
Вот метод Java, который я хочу вызвать через код JNI выше:

public int getCode() {
return code;
}

Оба объекта, mvclass и mid, созданы должным образом и должны функционировать, если я что-то не упустил.

ОБНОВЛЕНИЕ 2

Если я запускаю следующий код, метод toString () работает с использованием той же концепции:

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;
}

Итак, метод toString () возвращает полное имя класса объекта, и это правильный объект RWException. Метод, описанный в первом обновлении getCode (), является общедоступным и т. Д., Поэтому не уверен, почему он выдает ошибку нарушения доступа к памяти.

1

Решение

// 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);

Ух ты.

И компилятор не жалуется на это, потому что каждый jclass это jobject, как jstring,

2

Другие решения

Единственная возможная проблема, которую я вижу в вашем коде, это то, что вы вызываете метод, пока исключение все еще распространяется. envLoc->ExceptionOccurred() дает вам объект исключения, но вы все равно должны его поймать envLoc->ExceptionClear(),

2

У вас нет проверки ошибок в этом коде. Вам необходимо проверить результат каждой операции JNI: GetObjectClass (), GetMethodID (), CallXXXMethod () … Например, вы предполагаете, что у класса есть метод getCode (), и вызываете его, не проверяя его.

1
По вопросам рекламы [email protected]