JNI获取异常信息 - 尝试读取或写入受保护的内存 [英] JNI Getting Exception Info - Attempted to read or write protected memory

查看:157
本文介绍了JNI获取异常信息 - 尝试读取或写入受保护的内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用下面的代码尝试并在java中获取一个类RWException(它扩展了Exception),以便我可以调用一个方法getCode()来检索错误代码(int)并正确处理错误。我经历了JNI文档,并创建了以下代码...问题是,我得到一个AccessViolation异常,当我试图调用无参数方法getCode()。我得到一个有效的句柄的类和我正在寻找的方法id。

  jstring o =(jstring)envLoc-> CallStaticObjectMethod(cls,mid,jstrUser,jstrPass,jstrGroup); 
jthrowable exc = envLoc-> ExceptionOccurred();

if(exc){
//获取类
jclass mvclass = env-> GetObjectClass(exc);
//方法$ b的获取方法ID jmethodID mid = env-> GetMethodID(mvclass,getCode,()I);
//调用方法
jint code = env-> CallIntMethod(mvclass,mid);
}

这段代码给我在VS.NET中调试时的异常:



尝试读取或写入受保护的记忆体



UPDATE
下面是我希望通过上面的JNI代码调用的java方法:

  public int getCode(){
;
}

mvclass和mid对象都被正确实例化,



如果我运行以下代码toString() )方法使用相同的概念:

  jstring o =(jstring)envLoc-> CallStaticObjectMethod(cls,mid,jstrUser, jstrPass,jstrGroup); 
exc = envLoc-> ExceptionOccurred();
if(exc){

envLoc-> ExceptionClear();

//获取类
jclass exccls = envLoc-> GetObjectClass(exc);

//方法的获取方法ID
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);

//这是发生访问冲突的地方
jint jcode = envLoc-> CallIntMethod(exccls,getCodeMeth);
int code = jcode;
}



因此,toString()方法返回对象的完整类名,它是正确的RWException对象。在第一次更新getCode()中概述的方法是public,etc ...因此不确定为什么它给出内存访问冲突错误。

解决方案

  // exc是异常对象
exc = envLoc-> ExceptionOccurred();

...

// exccls是异常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是CLASS,而不是对象
//所以正确的是:
jint jcode = envLoc-> CallIntMethod(exc,getCodeMeth);

哦哇。



不会抱怨,因为每个 jclass 是一个 jobject ,就像 jstring


I'm using the following code to try and obtain a class RWException (which extends Exception) in java so that I can call a method "getCode()" to retrieve an error code (int) and handle the error properly. I went through the JNI docs and created the following code... problem is I am getting an AccessViolation exception when I attempt to call the parameterless method getCode(). I get a valid handle for the class and the method id I am looking for.

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

This code gives me an exception while debugging inVS.NET w/ the following info:

Attempted to read or write protected memory

UPDATE Here is the java method I wish to invoke via JNI code above:

public int getCode() {
    return code;
}

Both the mvclass and mid objects are instantiated properly and should function unless I am missing something.

UPDATE 2

If I run the following code the toString() method works using the same concept:

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

So, the toString() method returns the full class name of the object and it's the correct RWException object. The method outlined in the first update getCode() is public, etc... so not sure why it gives a memory access violation error.

解决方案

// 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.

And the compiler doesn't complain about this because every jclass is a jobject, just like jstring.

这篇关于JNI获取异常信息 - 尝试读取或写入受保护的内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆