目录
Java Native 关键字实践
/    

Java Native 关键字实践

Java Native 关键字实践

Java 平台有个用户和本地 C 代码进行交互操作的 API,成为 Java Native Interface (JNI)

java是跨平台的语言,既然是跨了平台,所付出的代价就是牺牲一些对底层的控制,而java要实现对底层的控制,就要一些其他语言的帮助,这个就是native的作用了

Java不是完美的,Java的不足除了体现在运行速度上要比传统的C++慢许多之外,Java无法直接访问到操作系统底层(如系统硬件等),为此Java使用native方法来扩展Java程序的功能。

大概流程:

1、在Java中声明native()方法,然后编译; 

2、用javah产生一个.h文件; 

3、写一个.cpp文件实现native导出方法,其中需要包含第二步产生的.h文件(注意其中又包含了JDK带的jni.h文件); 

4、将第三步的.cpp文件编译成动态链接库文件; 

5、在Java中用System.loadLibrary()方法加载第四步产生的动态链接库文件,这个native()方法就可以在Java中被访问了。

JAVA本地方法适用的情况

1.为了使用底层的主机平台的某个特性,而这个特性不能通过JAVA API访问

2.为了访问一个老的系统或者使用一个已有的库,而这个系统或这个库不是用JAVA编写的

3.为了加快程序的性能,而将一段时间敏感的代码作为本地方法实现。

实践测试

1、创建测试类

package cn.lacknb.test.jni;

/**
 * <h2>  </h2>
 *
 * @author: gitsilence
 * @description:
 * @date: 2022/9/24 09:02
 **/
public class HelloNative {

    static {
        System.loadLibrary("libHelloNative");
    }

    public static native void sayHello();

    public static void main(String[] args) {
        sayHello();
    }

}

2、编译、导出头文件

这里创建的类有包名,当前就处于cn.lcknb.test.jni 的目录下

编译

javac -d ../../../../ HelloNative.java

导出头文件

到 main/java 目录下,执行

javah cn.lacknb.test.jni.HelloNative

然后会生成文件 cn_lacknb_test_jni_HelloNative.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include </Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/include/jni.h>
/* Header for class cn_lacknb_test_jni_HelloNative */

#ifndef _Included_cn_lacknb_test_jni_HelloNative
#define _Included_cn_lacknb_test_jni_HelloNative
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     cn_lacknb_test_jni_HelloNative
 * Method:    sayHello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_cn_lacknb_test_jni_HelloNative_sayHello
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

这里的 jni.h 我改成了绝对路径,具体目录在 $JAVA_HOME/include,但是 jni.h 引用了 jni_md.h ,这个文件macOS 系统下是在 $JAVA_HOME/inclde/darwin

3、创建 C 语言文件,写具体调用方法

HelloNative.c

#include "cn_lacknb_test_jni_HelloNative.h"
#include <stdio.h>

JNIEXPORT void JNICALL Java_cn_lacknb_test_jni_HelloNative_sayHello() {
    printf("Hello JNI ...");
    return;
}

4、编译 c 代码、并导出成动态链接库

动态库名字必须为libxxxx.dylib(xxxx=文件名)

不同的操作系统的操作链接库的后缀是不一样的。

window:.dll

linux:.so

macOS: .dylib

编译命令:

clang -c HelloNative.c

生成动态链接库

clang -shared HelloNative.o -o libHelloNative.dylib

5、将动态链接库复制到目录:$JAVA_HOME/jre/lib/

6、运行 Java 代码 HelloNative 的 main 方法

Hello JNI ...


标题:Java Native 关键字实践
作者:gitsilence
地址:https://blog.lacknb.cn/articles/2022/09/27/1664259983306.html