2023-01-19 394
我想确定使用JNI从C ++代码调用该函数时,Java函数抛出了什么例外.我有以下代码捕获Java例外:
JNIEnv * pEnv; // assume this is properly initialized
jclass javaClass; // ditto
jmethodID javaFunction; // ditto
pEnv->CallStaticVoidMethod(javaClass, javaFunction);
jthrowable exc;
if(exc = pEnv->ExceptionOccurred())
{
pEnv->ExceptionClear();
}
我不知道如何在此C ++代码中获取有关Java异常的描述性信息.有人可以帮忙吗?
我省略了调用ExceptionCheck()在每次JNI调用并检查任何未能以简洁定位方法的尝试失败的尝试:您应该在实现时添加这些方法.
首先,存储异常,然后获取获得有关Throwable的信息所需的Java方法:
// Get the exception and clear as no
// JNI calls can be made while an exception exists.
jthrowable exception = pEnv->ExceptionOccurred();
pEnv->ExceptionClear();
jclass throwable_class= pEnv->FindClass("java/lang/Throwable");
jmethodID mid_throwable_getCause =
pEnv->GetMethodID(throwable_class,
"getCause",
"()Ljava/lang/Throwable;");
jmethodID mid_throwable_getStackTrace =
pEnv->GetMethodID(throwable_class,
"getStackTrace",
"()[Ljava/lang/StackTraceElement;");
jmethodID mid_throwable_toString =
pEnv->GetMethodID(throwable_class,
"toString",
"()Ljava/lang/String;");
jclass frame_class= pEnv->FindClass("java/lang/StackTraceElement");
jmethodID mid_frame_toString =
pEnv->GetMethodID(frame_class,
"toString",
"()Ljava/lang/String;");
第二,递归构造错误消息(您可能需要修改此消息):
std::string error_msg; // Could use ostringstream instead.
_append_exception_trace_messages(*pEnv,
error_msg,
exception,
mid_throwable_getCause,
mid_throwable_getStackTrace,
mid_throwable_toString,
mid_frame_toString);
void _append_exception_trace_messages(
JNIEnv& a_jni_env,
std::string& a_error_msg,
jthrowable a_exception,
jmethodID a_mid_throwable_getCause,
jmethodID a_mid_throwable_getStackTrace,
jmethodID a_mid_throwable_toString,
jmethodID a_mid_frame_toString)
{
// Get the array of StackTraceElements.
jobjectArray frames =
(jobjectArray) a_jni_env.CallObjectMethod(
a_exception,
a_mid_throwable_getStackTrace);
jsize frames_length = a_jni_env.GetArrayLength(frames);
// Add Throwable.toString() before descending
// stack trace messages.
if (0 != frames)
{
jstring msg_obj =
(jstring) a_jni_env.CallObjectMethod(a_exception,
a_mid_throwable_toString);
const char* msg_str = a_jni_env.GetStringUTFChars(msg_obj, 0);
// If this is not the top-of-the-trace then
// this is a cause.
if (!a_error_msg.empty())
{
a_error_msg += "\nCaused by: ";
a_error_msg += msg_str;
}
else
{
a_error_msg = msg_str;
}
a_jni_env.ReleaseStringUTFChars(msg_obj, msg_str);
a_jni_env.DeleteLocalRef(msg_obj);
}
// Append stack trace messages if there are any.
if (frames_length > 0)
{
jsize i = 0;
for (i = 0; i < frames_length; i++)
{
// Get the string returned from the 'toString()'
// method of the next frame and append it to
// the error message.
jobject frame = a_jni_env.GetObjectArrayElement(frames, i);
jstring msg_obj =
(jstring) a_jni_env.CallObjectMethod(frame,
a_mid_frame_toString);
const char* msg_str = a_jni_env.GetStringUTFChars(msg_obj, 0);
a_error_msg += "\n ";
a_error_msg += msg_str;
a_jni_env.ReleaseStringUTFChars(msg_obj, msg_str);
a_jni_env.DeleteLocalRef(msg_obj);
a_jni_env.DeleteLocalRef(frame);
}
}
// If 'a_exception' has a cause then append the
// stack trace messages from the cause.
if (0 != frames)
{
jthrowable cause =
(jthrowable) a_jni_env.CallObjectMethod(
a_exception,
a_mid_throwable_getCause);
if (0 != cause)
{
_append_exception_trace_messages(a_jni_env,
a_error_msg,
cause,
a_mid_throwable_getCause,
a_mid_throwable_getStackTrace,
a_mid_throwable_toString,
a_mid_frame_toString);
}
}
}
我从几年前编写的代码中复制了这篇文章(修改以消除锅炉板ExceptionCheck() s),但我没有编译我发布的内容,但有望很清楚.
如果您只是对例外的堆栈跟踪感兴趣,则可以:
if (env->ExceptionOccurred()) // check if an exception occurred
{
env->ExceptionDescribe(); // print the stack trace
}
简单的方法是声明JNI方法以投掷所有可能的例外,然后:
jthrowable throwable = ExceptionOccurred(env);
if (throwable != NULL)
Throw(env, throwable);
,让您的Java代码处理它.
以上所述是小编给大家介绍的使用JNI时,如何获得C ++中Java异常的描述?,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!
原文链接:https://77isp.com/post/25752.html
=========================================
https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。
数据库技术 2022-03-28
网站技术 2022-11-26
网站技术 2023-01-07
网站技术 2022-11-17
Windows相关 2022-02-23
网站技术 2023-01-14
Windows相关 2022-02-16
Windows相关 2022-02-16
Linux相关 2022-02-27
数据库技术 2022-02-20
抠敌 2023年10月23日
嚼餐 2023年10月23日
男忌 2023年10月22日
瓮仆 2023年10月22日
簿偌 2023年10月22日
扫码二维码
获取最新动态