如何快速使用JNI

发布于:2024-06-30 ⋅ 阅读:(17) ⋅ 点赞:(0)

1_JNI是什么?

JNI 是Java Native Interface的缩写,通过JNI,允许Java代码与其他语言(通常是C或C++)编写的本地应用程序或库进行交互。简而言之就是,Java可以通过JNI调用C 或 C++ 语言写的代码。

2_使用

1、首先,准备一个demo让我们进行JNI的快速入门使用:

/**
 * @author shenyang
 * @version 1.0
 * @info JNI
 * @since 2024/6/29 下午5:03
 */
public class JNIDemo {
    public static void main(String[] args) {
    	System.out.println(System.getProperty("java.library.path"));
        System.out.println(add(1,2));
    }
}

2、需要将C/C++实现的方法用native关键字声明。

  • native关键字声明的方法我们就不需要给出方法体了,直接给出声明就好了。
public static native int add(int a, int b);//这个方法的作用是将两个整型相加

3、加载动态链接库(windows.dll为后缀,linux上.so为后缀名),通常是使用静态代码块来进行导入。

  • 使用 System对象的 public static void loadLibrary(String libname)方法不需要后缀,只要(库所在路径加上)库名。
static {
    System.loadLibrary("jniDemo");
}

4、使用 javac -hjavah生成.h为后缀的头文件

javac -h ./ JNIDemo.java
  • 生成的头文件JNIDemo.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h> //这个头文件在jdk/include/下
/* Header for class JNIDemo */

#ifndef _Included_JNIDemo
#define _Included_JNIDemo
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     JNIDemo 说明这个方法是在哪个类里
 * Method:    add     对应的是java中的add方法
 * Signature: (II)I	  括号里两个II表示第一个参数和第二个参数都是int类型,括号后面的I表示这个方法的返回值是int类型
 * 下面这部分是C++需要实现的函数声明
 */
JNIEXPORT jint JNICALL Java_JNIDemo_add
  (JNIEnv *, jclass, jint, jint);

#ifdef __cplusplus
}
#endif
#endif

下面这部分是C++需要实现的函数声明:

JNIEXPORT jint JNICALL Java_JNIDemo_add
  (JNIEnv *, jclass, jint, jint);

5、根据生成的头文件里的函数声明实现对应的函数,创建JNIDemo.cpp文件。

  • 注意:下面的代码包含了之前生成的头文件JNIDemo.h,还需要其他头文件也可以一并包含进去,比如:iostream
  • 下面四个参数:JNIEnv *是一个指针封装了一些JNI的操作在里面,jclass参数也用不到只放一个参数类型就行了,后面两个参数因为用的到所以把参数名加上。
  • 函数的最终目的是返回a+b,再加上一些其他操作我们进行测试;
#include "JNIDemo.h"
#include <iostream>

JNIEXPORT jint JNICALL Java_JNIDemo_add(JNIEnv *, jclass , jint a, jint b)
{
    std::cout <<"a = "<< a<<"	b= "<< b <<std::endl;
    return a+b;
}

6、将上面的cpp文件编译成动态链接库。

给对C++不太了解的同学解释下下面命令的意义:

  • -o jniDemo.dll: 指定输出文件的名称为jniDemo.dll(与System.loadLibrary("jniDemo")中保持统一)。在Windows系统上,动态链接库通常以.dll为扩展名。

  • -fPIC: 表示生成位置无关代码(Position-Independent Code)。这是生成共享库时常用的选项,使得生成的代码在加载到内存中的任何位置时都可以正确运行。

  • -shared: 指定生成一个共享库(动态链接库),而不是可执行文件。

  • -I: 包含路径选项,用于指定头文件所在目录。在这里,包含了特定于Windows系统的Java头文件。

  • JNIDemo.cpp: 源文件名,包含了具体的JNI方法实现。

  • 如果windows电脑上使用不了g++命令,那么可以下载MinGWX64 - x86_64-win32-sjlj

g++ -o jniDemo.dll -fPIC -shared -I"E:\shenyang\.jdks\jdk-1.8\include\win32" -I"E:\shenyang\.jdks\jdk-1.8\include" JNIDemo.cpp

执行完毕后发先目录下出现jniDemo.dll文件:

在这里插入图片描述

最后运行 JNIDemo.java ,查看运行结果:

在这里插入图片描述

3_扩展

基础数据类型对应表:

Java 类型 JNI 类型 C/C++ 类型 描述
boolean jboolean unsigned char 布尔类型,值为truefalse ,使用0表示false,非0表示true
byte jbyte signed char 8位有符号整数
char jchar unsigned short 16位无符号Unicode字符
short jshort short 16位有符号整数
int jint int 32位有符号整数
long jlong long long 64位有符号整数
float jfloat float 32位单精度浮点数
double jdouble double 64位双精度浮点数
void void void 无类型

引用数据类型对应表:

Java 类型 JNI 类型 描述
String jstring Java字符串
Object jobject 任意Java对象
Class jclass Java类
Throwable jthrowable Java异常对象
boolean[] jbooleanArray 布尔型数组
byte[] jbyteArray 字节型数组
char[] jcharArray 字符型数组
short[] jshortArray 短整型数组
int[] jintArray 整型数组
long[] jlongArray 长整型数组
float[] jfloatArray 单精度浮点型数组
double[] jdoubleArray 双精度浮点型数组
任意类型的对象数组 jobjectArray 对象数组
Java数组中的任意类型 jarray 通用数组类型

网站公告

今日签到

点亮在社区的每一天
去签到