Java中 JNI 本地方法调用报错怎么将 C/C++ 错误码包装为 NativeExecutionException

星磊酱_9652

星磊酱_9652

2026-07-15

926人浏览

原创

应将c/c++错误码转换为java自定义异常nativeexecutionexception,通过jni的findclass、getmethodid、newobject和throw组合抛出带错误码的异常实例,并确保不调用exceptionclear或继续执行逻辑。

java中 jni 本地方法调用报错怎么将 c/c++ 错误码包装为 nativeexecutionexception

<p>在 Java 中通过 JNI 调用 C/C++ 本地方法时,若底层发生错误(如内存分配失败、系统调用返回 errno、自定义业务错误),不应直接让 JVM 崩溃或抛出模糊的 <code>RuntimeException</code>,而应将 C/C++ 错误码转换为结构化的 Java 异常,比如自定义的 <code>NativeExecutionException</code>。关键在于:C 层捕获错误 → 封装错误码与上下文信息 → 主动触发 Java 异常抛出。</p>

<h3>定义 NativeExecutionException 类</h3>
<p>先在 Java 层定义一个带错误码、错误消息和可选原始上下文的运行时异常:</p>
<p><font color="#888"><!-- 示例 --></font></p><div class="aritcle_card flexRow artxards">
											<div class="artcardd flexRow">
												<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill6235" title="Java Maven Code Review"><img
														src="https://img.php.cn/upload/skill/000/000/081/179084711841712.jpg" alt="Java Maven Code Review" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
												<div class="aritcle_card_info flexColumn">
													<a rel="nofollow" href="/xiazai/skill6235" title="Java Maven Code Review" class="overflowclass">Java Maven Code Review</a>
													<p class="overflowclass">审查Java Maven项目(ZIP压缩包或GitLab仓库URL),检查代码规范、命名、模块边界、可维护性问题以及重复代码。</p>
												</div>
												<a rel="nofollow" href="/xiazai/skill6235" title="Java Maven Code Review" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
												</a>
											</div>
										</div>
<p><strong>public class NativeExecutionException extends RuntimeException {</strong><br>
  <strong>private final int errorCode;</strong><br>
  <strong>public NativeExecutionException(int errorCode, String message) {</strong><br>
    <strong>super(message);</strong><br>
    <strong>this.errorCode = errorCode;</strong><br>
  <strong>}</strong><br>
  <strong>public int getErrorCode() { return errorCode; }</strong><br><strong>}</strong></p>

<h3>在 JNI 函数中主动抛出 Java 异常</h3>
<p>C/C++ 层不能直接“throw”,需借助 JNI 接口:<code>FindClass</code> 获取异常类,<code>NewStringUTF</code> 构造消息,<code>ThrowNew</code> 触发抛出。注意:抛出后应立即返回,避免后续逻辑干扰 JVM 状态。</p>
  • 检查本地函数返回值或 errno,确定是否出错
  • 调用 env->FindClass("com/example/NativeExecutionException") 获取 Class 对象
  • 用 env->NewStringUTF("Failed to open device: ENOENT") 创建消息字符串
  • 调用 env->ThrowNew(clazz, msgStr) 抛出异常
  • 函数返回前确保不执行可能崩溃的代码(如解引用空指针)

传递错误码到 Java 异常构造器

JNI 不支持直接调用带 int 参数的异常构造器,需改用反射方式或预设构造器签名。推荐做法是:在 Java 异常类中提供接受 (int, String) 的构造器,并在 JNI 中通过 GetMethodID + NewObject + Throw 组合实现完整对象抛出:

  • 获取构造方法 ID:jmethodID ctor = env->GetMethodID(clazz, "<init>", "(ILjava/lang/String;)V");
  • 创建 Java 字符串:jstring msg = env->NewStringUTF("Invalid handle");
  • 新建异常实例:jthrowable ex = (jthrowable)env->NewObject(clazz, ctor, 999, msg);
  • 抛出:env->Throw(ex);
  • 注意释放局部引用(如 msg, ex)避免内存泄漏

确保异常不被 JVM 吞掉或静默忽略

JNI 函数返回后,JVM 会检测是否有待处理异常。但若 Java 调用方未显式检查或 try-catch,异常会上抛。需注意:

  • 不要在 JNI 函数里调用 ExceptionClear(),否则会清除刚抛出的异常
  • 避免在抛出异常后继续执行 JNI 逻辑(如调用 ReleaseStringUTFChars 但未检查是否成功)
  • Java 调用侧应明确捕获 NativeExecutionException 并根据 getErrorCode() 分支处理
  • 可在 JNI 库初始化时缓存 Class 和 MethodID,提升性能并减少查找失败风险

Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

9697

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

6842

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

6052

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1064

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

868

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1276

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2549

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

19871

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1155

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习