JNI的使用

JAVA基础知识

Package机制

功能:

  1. 把功能相似或相关的类或接口组织在同一个包中 --- 集中管理类
  2. 如同文件夹一样,包也采用了树形目录的存储方式。同一个包中的类名字是不同的,
    不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,
    应该加上包名加以区别 --- 避免类名冲突
  3. 包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类 --- 权限
    例子:
    创建com.test包
package com.test
public class A implements B{
	public void testA(){
	}
}

编译流程

java源代码(符合语言规范)-->javac-->.class(二进制文件)-->jvm-->机器语言(不同平台不同种类)

Javac、Javah和Java

Javac: 编译命令,将Java源文件编译成.class字节码文件。
-encoding 指定源文件的文件编码格式
Javah: 生成实现本地方法所需的C头文件和源文件。
Java: 运行字节码文件,由JVM对字节码进行解释和运行。

JNI(Java Native Interface)使用流程

  1. 创建JAVA文件Algorithm.java,并创建包和接口类,接口声明为native,如public native int GetA();
  2. 使用Javah工具生成C头文件 com_alg_Algorithm.h,命令"javah com.alg.Algorithm";
  3. 根据C头文件实现C代码Algorithm.cpp,并生成.so(linux)或.dll(windows)动态库文件;
  4. Java代码LoadLibrary加载动态库,调用native代码,命令"javac test.java"

代码示例:Algorithm.java-步骤一

package com.alg;
public class Algorithm
{
	public native int GetA();
	public native int GetB();
}

代码示例com_alg_Algorithm.h-步骤二

JNIEXPORT jint JNICALL Java_com_alg_Algorithm_GetA();
JNIEXPORT jint JNICALL Java_com_alg_Algorithm_GetB();

代码示例algorithm.cpp-步骤三

#include"com_alg_Algorithm.h"
//"jni.h"在安装JDK目录include中可以得到
#include"jni.h"
#include<iostream>

JNIEXPORT jint JNICALL Java_com_alg_Algorithm_GetA()
{
      std::cout << "Hello World A!" << std::endl;
      return 0;
}

JNIEXPORT jint JNICALL Java_com_alg_Algorithm_GetA()
{
      std::cout << "Hello World B!" << std::endl;
      return 0;
}

代码示例test.java-步骤四

import com.alg.Algorithm;
import java.io.IOException;
import java.io.InputStream;
public class Test
{
      static
      {
            System.loadLibrary("Algorithm");
      }
      public static void main(String[] args) throws IOException
      {
            Algorithm alg = new Algorithm();
            alg.GetA();
            alg.GetB();
      }
}

特别注意点

javah生成的头文件中函数的命名,是根据java类Algorithm存在的路径来名,以下述接口名为例:

jint JNICALL Java_com_alg_Algorithm_GetA()

对应java存在的路径为:app\src\main\java\com\alg\Algorithm。
也就是说若javah生成的接口名与调用接口的java文件路径不一致时会导致接口无法正常被调用。

JNA(Java Native Access)

需求: 很少有java程序员愿意编写调用.dll/.so库中原生函数的java程序。
解决: 它提供一组java工具类用于在运行期间动态访问系统本地共享类库,
java开发人员只要在一个java接口中描述目标native library的函数与结构,
JNA将自动实现Java接口到native function的映射,而不需要编写任何Native/JNI代码,
大大降低了Java调用本体共享库的开发难度。

参考网站

Javac编译原理

posted @ 2020-12-23 20:00  Jefflnb  阅读(250)  评论(0编辑  收藏  举报