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();
   }
}
AI 代码解读

编写完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
AI 代码解读

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

c源文件代码如下:

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

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

这里使用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);  
AI 代码解读
目录
打赏
0
0
0
0
33
分享
相关文章
非常实用的Http应用框架,杜绝Java Http 接口对接繁琐编程
UniHttp 是一个声明式的 HTTP 接口对接框架,帮助开发者快速对接第三方 HTTP 接口。通过 @HttpApi 注解定义接口,使用 @GetHttpInterface 和 @PostHttpInterface 等注解配置请求方法和参数。支持自定义代理逻辑、全局请求参数、错误处理和连接池配置,提高代码的内聚性和可读性。
224 3
|
2月前
|
在Java中如何实现接口?
实现接口是 Java 编程中的一个重要环节,它有助于提高代码的规范性、可扩展性和复用性。通过正确地实现接口,可以使代码更加灵活、易于维护和扩展。
218 64
|
2月前
|
在 Java 中,一个类可以实现多个接口吗?
这是 Java 面向对象编程的一个重要特性,它提供了极大的灵活性和扩展性。
183 57
|
2月前
|
在Java中实现接口的具体代码示例
可以根据具体的需求,创建更多的类来实现这个接口,以满足不同形状的计算需求。希望这个示例对你理解在 Java 中如何实现接口有所帮助。
100 38
利用Java获取京东SKU接口指南
本文介绍如何使用Java通过京东API获取商品SKU信息。首先,需注册京东开放平台账号并创建应用以获取AppKey和AppSecret。接着,查阅API文档了解调用方法。明确商品ID后,构建请求参数并通过HTTP客户端发送请求。最后,解析返回的JSON数据提取SKU信息。注意遵守API调用频率限制及数据保护法规。此方法适用于电商平台及其他数据获取场景。
|
1月前
|
java如何请求接口然后终止某个线程
通过本文的介绍,您应该能够理解如何在Java中请求接口并根据返回结果终止某个线程。合理使用标志位或 `interrupt`方法可以确保线程的安全终止,而处理好网络请求中的各种异常情况,可以提高程序的稳定性和可靠性。
55 6
|
2月前
|
Java中内置的函数式接口
Java中内置的函数式接口
40 2
|
2月前
|
在Java中,接口之间可以继承吗?
接口继承是一种重要的机制,它允许一个接口从另一个或多个接口继承方法和常量。
179 1
|
2月前
|
Eclipse 创建 Java 接口
Eclipse 创建 Java 接口
44 1
|
2月前
|
java线程接口
Thread的构造方法创建对象的时候传入了Runnable接口的对象 ,Runnable接口对象重写run方法相当于指定线程任务,创建线程的时候绑定了该线程对象要干的任务。 Runnable的对象称之为:线程任务对象 不是线程对象 必须要交给Thread线程对象。 通过Thread的构造方法, 就可以把任务对象Runnable,绑定到Thread对象中, 将来执行start方法,就会自动执行Runable实现类对象中的run里面的内容。
49 1
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等