JNI原理是什么?JNI在DDS binding JAVA中/DDS移植android平台中有什么作用?

1 JNI是什么

总结几点重要的如下:

  1. JNI是用来实现java代码和本地native方法(比如一些C C++实现的代码)之间交互的一种框架,同时也是java标准里面的一部分,是Java平台定义的规范接口;
    private native void native_init();
    private native void native_sub(int domainID);

点击这些native方法进行跳转,可以看到native方法的实现是C++代码所完成,即native方法的实现;
在这里插入图片描述

  1. 为了更好的与操作系统级别以及硬件级别交互,并且为了完成某些计算密集型的任务,很多本地代码都是通过C、C++来实现的,这要比纯java代码高效一些。然后java代码JNI与这些底层代码进行交互;
  2. java代码通过JNI来调用本地方法(本地方法就是关键字为native的java方法,并且不能有方法体), 所以JNI也是一个桥梁;也可以说通过JNI可以将C/C++代码集成在Java中
  3. 使用native关键字将某方法声明为本地实例方法,这就很明显地告诉JVM:这个方法实现在另外一个语言中(C/C++),请去那里寻找他的实现

2 如何在JAVA中调用C/C++方法(通过JNI调用的demo)

整体的调用逻辑就在这张图上面

1、创建一个java源码,并且里面声明一个native关键字修饰的本地方法,该方法没有方法体;
2、通过javah工具,或者javac -h 产生JNI的.h头文件,过程中会同时产生.class文件。产生JNI头文件所需要的官方jni.h和jni_md.h都在JDK11 的安装包里面;
3、然后实现一个.c文件,这个.c文件就是真正要干的事情,而且JNI头文件和.c之间是有一定的对应关系的。
4、然后将.c文件通过gcc生成win下的共享库.dll
5、运行java。通过javac产生.class字节码文件,然后通过java XXX的命令运行起来。这时候java虚拟机会去通过System.loadLibrary调用共享库,找到native方法的C实现的代码,执行里面的流程

在这里插入图片描述
注意:javah到.h这一步,可能通过javac -h . XXX.java替代

🐵下面通过例子来描述:

java中声明一个本地native方法

java当中有个很重要的点,一个源文件中可以有多个类,但是只有一个public类。而且源文件的名称必须与public类的名称相同;

package org.example;

public class HelloJNI {
    static {
        System.loadLibrary("hello");
    }

    private native void sayHello();

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

生成JNI头文件

在终端javac -h . D:\IDC\Android\testJNI\src\main\java\org\example\HelloJNI.java 告诉 javac 编译器生成一个 C/C++ 头文件(JNI 头文件),以便与本地代码(如 C 或 C++)交互。javac XX.java是产生java的中间文件
请注意这里我写的java文件的绝对路径,后面会解释,接着往后走

1、 javac:Java 编译器,用于编译 Java 源文件。
2、-h .:-h 选项告诉 javac 生成一个 JNI 头文件,. 表示将头文件放置在当前目录下。
3、HelloJNI.java:指定要编译的 Java 源文件。

生成头文件可以通过javac -h <dir> XX.java ,也可以通过javah -d 的方式,javac -hjavah 都可以用于生成 JNI 头文件,但 javac -h 更倾向于在编译 Java 源文件的过程中生成头文件,而 javah 是一个独立的工具,主要用于生成头文件

如下图所示,生成了头文件org_example_HelloJNI.h
在这里插入图片描述
在这里插入图片描述

Java native方法转换成C的规则与语法说明

上面的生成函数中,可以看到JNI中生成的C函数是:Java_org_example_HelloJNI_sayHello (JNIEnv *, jobject);

  1. JNIEnv *:指向JNI运行环境的指针,可通过这个指针访问JNI函数
  2. jobject:java中的this对象
  3. extern “C” : 告诉编译器,这是C函数;

所以其规则是:Java_{package_and_classname}_{function_name}(JNI arguments),Java_包名_类名_native方法名

C实现的native方法本地实现以及.o .dll库的生成

HelloJNI.c代码如下,打印一行字符即可。

#include <jni.h>
#include <stdio.h>
//#include "HelloJNI.h"

// Implementation of native method sayHello() of HelloJNI class
JNIEXPORT void JNICALL Java_org_example_HelloJNI_sayHello(JNIEnv *env, jobject thisObj) {
   printf("Hello World!\n");
   return;
}

通过JDK编译HelloJNI.c文件产生.o 文件

gcc -c -I "D:\JDK11\include" -I "D:\JDK11\include\win32" HelloJNI.c

其中jni.h文件分别在JAVA_HOME下的include和include\win32下面

然后通过JDK编译HelloJNI.c文件产生.dll文件
在这里插入图片描述
注意不要在终端里面操作,powershell会认为某些参数不对
直接在黑窗口操作就不会报错
在这里插入图片描述
如下图所示
在这里插入图片描述
三种文件分别是:.C是源文件;.o是中间文件,还没有被链接成可执行文件或者库文件;.dll是win下的动态链接库;

查看hello.dll库中的函数

如果是在linux上面的话使用:nm hello.dll | grep say
如果是在win环境编的,在黑窗口中用:objdump -t hello.dll | findstr /R /C:"say"
在这里插入图片描述

运行一下HelloJNI

打印的hello,world
请注意,如果我们想要通过JDK编译java产生.class文件后运行的话,必须后面跟着绝对路径,这里报错了好久,先这么记下。
在这里插入图片描述

JNI在DDS移植android平台的作用

持续更新…

【参考文献】
JNI基础知识总结
Java——本地方法(JNI)详解
Java Native Interface(JNI)从零开始详细教程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江南霹雳堂雷家雷无桀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值