引言
在许多 Java 项目中,开发者常常需要调用 C/C++ 编写的代码,以便借助其性能优势或利用已有的库。为了实现 Java 与本地 C/C++ 代码的无缝对接,我们使用 JNI(Java Native Interface)。本文将详述如何在 IntelliJ IDEA 和 CLion 中搭建 JNI 开发环境,并通过一个简单的示例来演示 JNI 的基本用法。
IntelliJ IDEA 配置
创建项目
项目命名为 StudentJNI。

创建文件夹
jni:用于存储生成的头文件。
lib:用于放置编译后的 C/C++ 动态库。

创建类
在 src 目录下创建 Student.java、StudentInfo.java、Test.java类。
java
public class Student {
public static void main(String[] args) {
System.out.println("Hello World!");
}
// 加载jni库
static {
try {
System.loadLibrary("jnilib");
}
catch(UnsatisfiedLinkError e) {
System.err.println(">>> Can not load library: " + e.toString());
}
}
// 声明native方法
public native long create_student(String name, int age, int score);
public native void print_student(long student);
public native int get_student_age(long student);
public native void set_student(long student, String name, int age, int score);
public native void update_student_info(long student, StudentInfo student_info);
public native void update_student_info2(long student, StudentInfo.Address[] address);
}
java
public class StudentInfo {
public String name;
public int id;
public int age;
public int score;
public int[][] schedule = new int[5][6];
public Address[] address = new Address[3];
public class Address {
public int area;
public int block;
public int house_num;
}
public StudentInfo() {
name = "None";
id = 0;
age = 0;
score = 0;
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 6; j++) {
schedule[i][j] = 0;
}
}
for (int i = 0; i < 3; i++) {
address[i] = new Address();
address[i].area = 0;
address[i].block = 0;
address[i].house_num = 0;
}
}
// 打印学生信息
public void print_student_info() {
System.out.println("==============");
System.out.println("name: " + name);
System.out.println("id: " + id);
System.out.println("age: " + age);
System.out.println("score: " + score);
System.out.println("schedule: ");
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 6; j++) {
System.out.print(schedule[i][j] + " ");
}
System.out.println();
}
System.out.println("address: ");
for (int i = 0; i < 3; i++) {
System.out.println(address[i].area + " " + address[i].block + " " + address[i].house_num);
}
System.out.println("==============");
}
}
java
public class Test {
public static void main(String[] args) {
System.out.println("Unit Test!");
Student student = new Student();
long stu = student.create_student("lzq", 21, 100);
student.print_student(stu);
System.out.println("1.age: " + student.get_student_age(stu));
student.set_student(stu, "gyq", 18, 59);
student.print_student(stu);
System.out.println("2.age: " + student.get_student_age(stu));
StudentInfo student_info = new StudentInfo();
System.out.println("复杂接口测试:");
student_info.print_student_info();
student.update_student_info(stu, student_info);
student_info.print_student_info();
// while(true) {
// student.update_student_info(stu, student_info);
// }
System.out.println("Unit Test End!");
}
}
生成头文件
为了方便后面的生成或者更新,这里添加将生成过程添加为一个快捷工具。
在Preferences--Tools--External Tools 下新建。
Name和Description随意,Name会在下面用到。重要的的下面三个:
- Program内容
$JDKPath$/bin/javah - Arguments内容
-classpath $OutputPath$ -d ./jni $FileClass$ - Working directory内容
$ProjectFileDir$。

运行Test代码生成class文件
接着类Hello上点击鼠标右键---External Tools--GenerateHeader生成头文件,在jni目录就生成com_yaojing_Student.h的文件了。
CLion设置
在CLion同样新建项目,命名为StudentJNI,Language standard选择哪个都可以,Library type选择shared

在Preferences--Build, Execution, Deployment--CMake中将Build directory修改为build/debug,同样添加Release并进行类似的设置。

设置目录结构如下:
build是编译过程生成目录include为引用的头文件src目录是源码目录
