一、完整示例
注意,示例引入的是 Rust 静态库!
java
/**
* @version: V1.0
* @author: 余衫马
* @description: 主函数
* @data: 2024-11-22 19:24
**/
public class MyResultHandler {
/**
* 声明一个本地方法,用于绑定到 Rust Channel 的生产者
* 参数传递一个 MyCallback 实例,绑定 Rust Channel 的消费者,消费者调用 doCallback 方法输出
*/
private static native void invoke(String input,MyCallback callback);
// 用于加载包含本地方法实现的本地库。
static {
System.loadLibrary("rust_jni_channel_test");
}
public static void main(String[] args) {
invoke("hello",new MyCallback());
System.out.println("start");
}
}

注意这里没有包名,

添加 libs 文件夹,把 dll 添加进来,注意不需要使用 .dll 后缀,

配置 pom 主入口 mainclass 路径,
XML
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<mainClass>MyResultHandler</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
配置 VM 启动参数,
XML
-Djava.library.path=D:\JWorkSpace\ChannelDeomo\libs

运行效果,可以看到执行成功

新增包路径,

XML
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.yushanma.MyResultHandler.invoke(Ljava/lang/String;Lcom/yushanma/callback/MyCallback;)V
at com.yushanma.MyResultHandler.invoke(Native Method)
at com.yushanma.MyResultHandler.main(MyResultHandler.java:27)
实际上会报错,这是因为 dll 的包路径没匹配上,

修改路径后,重新编译,


此时运行成功。
二、JNI原理
Java Native Interface(JNI)是Java平台提供的编程框架,用于实现Java代码与其他语言(如C/C++)编写的本地代码交互。其核心原理是通过预定义的接口规范,在Java虚拟机(JVM)中调用本地方法或反之。JNI通过以下机制工作:
- 本地方法声明 :Java代码中通过
native关键字声明方法,但不提供实现,实际逻辑由本地库完成。 - 动态库加载 :使用
System.loadLibrary()加载包含本地代码的动态链接库(如Windows的.dll或Linux的.so)。 - 类型映射 :JNI定义Java类型与本地类型(如
jint对应int)的转换规则,确保数据传递的正确性。 - JNI函数表 :本地代码通过
JNIEnv*指针访问JNI函数表,调用JVM功能(如创建Java对象、抛出异常等)。
三、JNI应用场景
- 性能敏感操作:如图像处理、加密算法等需要直接操作硬件或高计算量的任务,本地代码通常性能更优。
- 遗留系统集成:复用现有C/C++库或驱动,避免重写已有功能。
- 平台特定功能:访问Java未封装的系统API(如特定硬件接口)。
- 跨语言混合开发:需结合Java与其他语言优势的场景(如游戏开发中Java处理逻辑,C++处理渲染)。
四、JNI优点
- 性能提升:本地代码可直接操作内存和硬件,避免JVM开销。
- 功能扩展:突破Java语言限制,实现底层系统调用或特定硬件控制。
- 代码复用:集成现有成熟库,减少重复开发成本。
五、JNI缺点
- 复杂性高:需处理跨语言数据类型转换、内存管理、线程同步等问题。
- 移植性差:本地库需针对不同平台编译,增加维护成本。
- 安全隐患:本地代码错误可能导致JVM崩溃或内存泄漏。
- 调试困难:跨语言调试工具链复杂,问题定位耗时。
六、企业级应用
高性能计算与科学模拟
JNI用于集成C/C++编写的高性能计算库(如BLAS、LAPACK),适用于金融建模、气象预测等需要密集计算的场景,显著提升Java应用的数值处理能力。
嵌入式系统与物联网
在工业物联网中,JNI调用底层硬件驱动(如传感器、PLC控制器),实现Java应用与嵌入式设备(Raspberry Pi、ARM芯片)的交互,满足实时控制需求。
游戏开发引擎
Unity等游戏引擎通过JNI接入Android NDK,优化图形渲染(OpenGL/Vulkan)和物理引擎,降低Java虚拟机开销,提升移动端游戏性能。
音视频处理
FFmpeg等多媒体库通过JNI被Java调用,用于实时音视频编解码(H.264/AV1)、流媒体直播(RTMP/WebRTC),满足短视频平台的高效处理需求。
区块链与加密安全
JNI集成OpenSSL或国密算法(SM2/SM3),实现硬件级加密(HSM/TEE),应用于数字货币交易、企业级区块链节点的密钥管理。
大数据分析
Hadoop/Spark通过JNI调用本地库(如Intel MKL、CUDA),加速矩阵运算和机器学习模型推理,处理PB级数据。
机器人控制框架
ROS(机器人操作系统)通过JNI与Java应用交互,实现工业机器人路径规划、SLAM算法的实时执行。
金融交易系统
高频交易平台使用JNI接入低延迟C++交易引擎(如QuickFix),实现纳秒级订单处理,同时利用Java的跨平台特性部署前端。
生物信息学
基因测序软件(如GATK)通过JNI调用C++编写的序列比对算法(BWA、Bowtie),加速DNA/RNA数据分析流程。
企业级数据库优化
MySQL/PostgreSQL的Java驱动通过JNI调用原生存储引擎(InnoDB),优化连接池管理和批量插入性能,支撑高并发OLTP场景。