JAVA本地接口(JNI)

简介:

JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他编程语言,只要调用约定受支持就可以了。使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的。例如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。JNI标准至少要保证本地代码能工作在任何Java 虚拟机环境下。
JNI编写步骤:

  1. 编写带有native声明的方法的java类
  2. 使用javac命令编译所编写的java类
  3. 使用javah + java类名生成扩展名为h的头文件
  4. 使用C/C++实现本地方法
  5. 将C/C++编写的文件生成动态连接库

首先,我们来编写JAVA类

public class HelloJNI
{
   // 所有native关键词修饰的都是对本地的声明
   public native void displayHelloJNI();

   static
   {
      // 载入本地动态链接库库
      System.loadLibrary("HelloJNI");
   }

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

编写完JAVA类后,我们需要对其进行编译获得字节码文件:javac HelloJNI.java

这里写图片描述

然后我们要生成扩展名为h的头文件:javah HelloJNI

生成的头文件内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloJNI */

#ifndef _Included_HelloJNI
#define _Included_HelloJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloJNI
 * Method:    displayHelloJNI
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_HelloJNI_displayHelloJNI
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

下面我们需要引入刚才生成的头文件并实现其方法,最终生成动态链接库。

c源文件代码如下:

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

JNIEXPORT void JNICALL Java_HelloJNI_displayHelloJNI(JNIEnv *env, jobject obj)
{
   printf("HelloJNI\n");
}

这里使用VC的编译器:cl -I%java_home%\include -I%java_home%\include\win32 -LD HelloJNIImpl.c -FeHelloJNI.dll

我们需要将生成的HelloJNI.dll放到JAVA的类路径下,最后运行JAVA程序。
控制台会输出:HelloJNI

到此,最简单的JNI编写过程已经完了。下面我们来总结一下。

JNI数据类型对应关系
基本类型

Java类型 本地C类型 说明
boolean jboolean 无符号8位整型(unsigned char)
byte jbyte 有符号8位整型(char)
char jchar 无符号16位整型(unsigned short)
short jshort 有符号16位整型(short)
int jint 有符号32位整型(int)
long jlong 有符号64位整型(long)
float jfloat 32位浮点型(float)
double jdouble 64位浮点型(double)

引用数据类型

Java类型 本地C类型 说明
Object jobject 任何JAVA对象,或者没有对应JAVA类型的对象
Class jclass Class类对象
String jstring 字符串对象
Object[] jobjectArray 任何对象的数组
boolean[] jbooleanArray 布尔型数组
byte[] jbyteArray 比特型数组
char[] jcharArray 字符型数组
short[] jshortArray 短整型数组
int[] jintArray 整型数组
long[] jlongArray 长整型数组
float[] jfloatArray 浮点型数组
double[] jdoubleArray 双浮点型数组

特殊类型

Java类型 本地C类型 说明
void void N/A

注意:
1. 引用数据类型则不能直接使用,需要根据JNI函数进行相应的转换后,才能使用。
2. 多维数组(包括二维数组)都是引用类型,需要使用 jobjectArray 类型存取其值 。

例如:二维整型数组就是指向一维数组的数组,其声明使用方式如下:

//获得一维数组 的类引用,即jintArray类型  
jclass intArrayClass = env->FindClass("[I");   
//构造一个指向jintArray类一维数组的对象数组,该对象数组初始大小为dimion  
jobjectArray obejctIntArray  =  env->NewObjectArray(dimion ,intArrayClass , NULL);  
目录
相关文章
|
10天前
|
算法 Java 数据处理
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其“不重复性”要求,彻底改变了处理唯一性数据的方式。
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其“不重复性”要求,彻底改变了处理唯一性数据的方式。HashSet基于哈希表实现,提供高效的元素操作;TreeSet则通过红黑树实现元素的自然排序,适合需要有序访问的场景。本文通过示例代码详细介绍了两者的特性和应用场景。
30 6
|
10天前
|
存储 Java 数据处理
Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位
【10月更文挑战第16天】Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位。本文通过快速去重和高效查找两个案例,展示了Set如何简化数据处理流程,提升代码效率。使用HashSet可轻松实现数据去重,而contains方法则提供了快速查找的功能,彰显了Set在处理大量数据时的优势。
20 2
|
2天前
|
安全 Java
在 Java 中使用实现 Runnable 接口的方式创建线程
【10月更文挑战第22天】通过以上内容的介绍,相信你已经对在 Java 中如何使用实现 Runnable 接口的方式创建线程有了更深入的了解。在实际应用中,需要根据具体的需求和场景,合理选择线程创建方式,并注意线程安全、同步、通信等相关问题,以确保程序的正确性和稳定性。
|
1天前
|
Java
Java基础(13)抽象类、接口
本文介绍了Java面向对象编程中的抽象类和接口两个核心概念。抽象类不能被实例化,通常用于定义子类的通用方法和属性;接口则是完全抽象的类,允许声明一组方法但不实现它们。文章通过代码示例详细解析了抽象类和接口的定义及实现,并讨论了它们的区别和使用场景。
|
1天前
|
Java 测试技术 API
Java零基础-接口详解
【10月更文挑战第19天】Java零基础教学篇,手把手实践教学!
8 1
|
6天前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
11 3
|
6天前
|
Java
在Java多线程编程中,实现Runnable接口通常优于继承Thread类
【10月更文挑战第20天】在Java多线程编程中,实现Runnable接口通常优于继承Thread类。原因包括:1) Java只支持单继承,实现接口不受此限制;2) Runnable接口便于代码复用和线程池管理;3) 分离任务与线程,提高灵活性。因此,实现Runnable接口是更佳选择。
18 2
|
6天前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
15 2
|
6天前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
16 1
|
7天前
|
Java 数据处理