我正在使用以下代码尝试在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);
}
这个代码在使用以下信息调试inVS.NET时给出了异常:
尝试读取或写入受保护的内存
更新 这是我希望通过上面的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()是公共的,等等...所以不确定为什么它会给出内存访问冲突错误。
答案 0 :(得分:2)
我能在代码中看到的唯一可能的问题是,在异常仍在传播时,您正在调用方法。 envLoc->ExceptionOccurred()
为您提供了异常对象,但您仍然必须使用envLoc->ExceptionClear()
实际捕获它。
答案 1 :(得分:2)
// 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 :(得分:1)
此代码中没有错误检查。您需要检查每个JNI操作的结果:GetObjectClass(),GetMethodID(),CallXXXMethod()...例如,您假设该类具有getCode()方法,并在不检查它的情况下调用它。