搭建 JNI 开发环境:使用 IntelliJ IDEA 和 CLion

引言

在许多 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目录是源码目录
相关推荐
阿维的博客日记1 天前
Hippo4j 线程池监控平台部署手册
java·spring boot·后端
C+++Python1 天前
详细介绍一下Java泛型的通配符
java·windows·python
JosieBook1 天前
【数据库】时序预测能力的分级进化:TimechoAI如何让每一类用户都能精准预见未来
java·开发语言·数据库
一生了无挂1 天前
Java处理JSON技巧教学(从基础到高阶实战全覆盖)
java·开发语言·json
李白的天不白1 天前
使用 SmartAdmin 进行前后端开发
java·前端
swordbob1 天前
Spring 单例 Bean 是线程安全的吗?
java·开发语言
2601_951643771 天前
Python第一,Java跌出前三,C语言杀回来了
java·c语言·python·编程语言排行·技术趋势
IT 行者1 天前
GitHub Spec Kit 实战(五):/speckit.tasks 怎么拆——Spec Kit 五部曲收官
java·ai编程·claude
(Charon)1 天前
【C++ 面试高频基础:指针、引用、const、static、new/delete 总结】
java·开发语言
Yeats_Liao1 天前
Feed流系统设计(三):数据模型与存储设计,从表结构到Redis收件箱
java·javascript·redis