JNI简单学习(java调用C/C++)

JNI

JNI(Java Native Interface)是 JDK 内置的标准原生接口,是 Java 平台与 C/C++ 等原生代码(Native Code)交互的底层规范,允许 Java 虚拟机(JVM)中的 Java 代码调用原生代码,也支持原生代码回调 Java 代码。与 JNA(基于 JNI 封装的上层类库)不同,JNI 是 Java 与原生代码通信的 "底层基础",所有 Java 调用原生库的方案(包括 JNA、JNR 等)最终都基于 JNI 实现。

核心组件

组件 作用
jni.h 核心头文件,定义 JNI 的类型、函数、宏(如JNIEnv、jobject、FindClass);
JNIEnv* 核心指针,提供 JNI 函数调用接口(如创建 Java 对象、调用 Java 方法、类型转换),线程私有;
JavaVM* Java 虚拟机实例指针,用于跨线程 / 跨进程获取JNIEnv,全局唯一;

关键类型映射(Java 对应 C/C++)

Java 类型 JNI 类型 C/C++ 类型
byte jbyte signed char
short jshort short
int jint int
long jlong long long(8 字节)
float jfloat float
double jdouble double
boolean jboolean unsigned char
char jchar unsigned short
String jstring 无直接映射(需通过 JNI 函数转换为 char*)
Object jobject 无直接映射(指向 Java 对象的指针)
数组 jarray/ jintArray/ jbyteArray 对应数组类型指针

演示

演示环境:

开发环境为:idea、visual studio

java版本:jdk-17.0.15

c++:ISO C++14 标准 (/std:c++14)

x64环境下

1.创建Java 类

创建一个名为JavaCode的maven项目

声明native方法

python 复制代码
public class NativeFunction 
{
	public native int add(int a, int b);
}

2.生成 JNI 头文件

通过Java 命令行生成包含方法签名的 C/C++ 头文件;

复制代码
javac -h jni NativeFunction.java

执行完以上命令后,会生成一个jni文件夹,里面的org_example_NativeFunction.h文件就是c/c++的头文件

3.编写 C/C++ 实现

创建一个名为CPPCode的空项目

将生成的头文件(org_example_NativeFunction.h)移动到头文件夹下

此时头文件(org_example_NativeFunction.h)里面会报错,在windows环境中需要引入2个头文件,分别为:

复制代码
jni.h
jni_md.h

这两个文件在java文件夹里面,比如下面这两个路径:

复制代码
D:\Program Files (x86)\java\jdk-17.0.15\include
D:\Program Files (x86)\java\jdk-17.0.15\include\win32

点击项目属性,将上面2个路径放进附加包含目录里面

补充:如果没有C/C++选项有可能是没创建C/C++文件导致的,创建了就好了(提前创建NativeFunction.cpp文件)

实现头文件(org_example_NativeFunction.h)中声明的原生方法

创建NativeFunction.cpp文件

cpp 复制代码
//引入头文件
#include "org_example_NativeFunction.h"

//实现方法,将需要使用的参数设置名称a,b
JNIEXPORT jint JNICALL Java_org_example_NativeFunction_add(JNIEnv*, jobject, jint a, jint b)
{
	return a + b;
}

4.编译动态库

根据自己的平台配置

项目属性设置为:

配置类型设置为:动态库

生成解决方案:

我的是x64环境

然后点击生成解决方案

在项目的 \x64\Debug 目录下会生成ddl文件

5.Java加载动态库

将编译好的dll动态库放进资源文件夹下:

编写加载动态库的代码,Java 加载动态库并调用 native 方法。

java 复制代码
public class Main 
{
	static 
	{
		//加载动态库
		String dllPath = System.getProperty("user.dir")+"\\src\\main\\resources\\CPPCode.dll";
		//不支持classpath
		System.load(dllPath);
	}
	
	public static void main(String[] args) 
	{
		//创建NativeFunction对象
		NativeFunction nativeFunction = new NativeFunction();
		//调用add方法
		int result = nativeFunction.add(5, 6);
		System.out.println("add(5, 6) = "+result);
	}
}

运行结果:

相关推荐
腻害兔7 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社8 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
萧瑟余晖9 小时前
JDK 26 新特性详解
java·开发语言
马优晨10 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
a11177611 小时前
2FA 验证码生成器(github登录验证 app)
笔记·学习
我的xiaodoujiao11 小时前
API 接口自动化测试详细图文教程学习系列32--Allure测试报告2
python·学习·测试工具·pytest
人邮异步社区12 小时前
怎么把C语言学到精通?
c语言·开发语言
维天说12 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json
Zane199413 小时前
并发 vs 并行:别再傻傻分不清了,一文讲透 Java 并发编程的第一课
java·后端
你想知道什么?13 小时前
线性回归-学习笔记
笔记·学习·线性回归