java - JNI 获取异常信息 - 试图读取或写入 protected 内存

标签 java c++ java-native-interface

我正在使用以下代码尝试在 Java 中获取 RWException 类(它扩展了 Exception),以便我可以调用方法“getCode()”来检索错误代码 (int) 并正确处理错误。我浏览了 JNI 文档并创建了以下代码...问题是当我尝试调用无参数方法 getCode() 时出现 AccessViolation 异常。我获得了该类的有效句柄和我正在寻找的方法 ID。

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 中调试时出现异常,其中包含以下信息:

试图读取或写入 protected 内存

更新 这是我希望通过上面的 JNI 代码调用的 java 方法:

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() 中概述的方法是公开的,等等...所以不确定为什么会出现内存访问冲突错误。

最佳答案

// 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 一样。

关于java - JNI 获取异常信息 - 试图读取或写入 protected 内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12325860/

相关文章:

c++ - 什么是指向成员模板参数的指针?

android - 来自 Android 的 OpenCV JNI 上的 SIGSEGV

java - 分析通过 JNI 调用运行的 Java

java - Keytool.exe 和 jarsigner.exe 问题

java - AWS lambda :Malformed Lambda proxy response

java - 模糊的条件 Java 语法

java - Spring 批处理 : How to catch exception message with skip method in spring batch?

c++ - 包括不工作的 guard ? (500 个类型为 LNK2005 x 的错误已在 y.obj 中定义)

c++ - 使用 C++ Boost 间隔容器库 (ICL) 时如何移动间隔?

android - 无法解析相应的 JNI 函数 Java_com_mozilla_greetings_RustGreetings_greeting