JNI方案说明和使用方法介绍

JNI(Java Native Interface)是Java平台用于与本地代码(如C/C++)交互的技术,允许Java代码调用本地函数和本地代码调用Java方法。本文详细介绍了JNI的基本概念,包括数据类型、引用的区别、jobject与jclass、描述符规则,以及如何通过GetEnv、NewGlobalRef、AttachCurrentThread、AllocObject等函数进行操作。同时,讲解了Java调用C++方法和C++调用Java方法的步骤、函数声明模板和注册方式,包括静态注册和动态注册的区别。最后,讨论了C++非JNI函数调用Java方法的实现方式。
摘要由CSDN通过智能技术生成

JNI简介

JNI(Java Native Interface)是Java编程语言中用于实现Java代码与本地(Native)代码(通常是C或C++代码)交互的机制。它允许Java应用程序调用本地代码中的功能,也可以让本地代码调用Java类和方法。JNI在Java平台上实现了Java与其他编程语言的互操作性。(即可互相调用)


主要目的和用途:

  • 访问本地功能: JNI允许Java程序通过调用本地代码来访问底层系统功能、硬件功能或第三方库,这些本地代码通常用C或C++编写。
  • 性能优化: 有时候,一些计算密集型任务在本地代码中执行可能比在Java中更高效。通过JNI,你可以将这些任务放在本地代码中,以提高性能。
  • 平台特定功能: JNI允许Java程序在需要平台特定功能的情况下,通过本地代码调用这些功能,以适应不同的操作系统和硬件环境。
  • 复用现有代码: 如果已经存在C/C++代码库,可以通过JNI将这些库集成到Java应用程序中,而无需重新实现相同的功能。



基本流程:

  • 编写本地代码: 首先,你需要编写C/C++代码实现要调用的功能。
  • 生成动态库: 将C/C++代码编译成动态链接库(.dll或.so文件),供Java代码调用。
  • Java接口定义: 在Java中,你需要编写一个与本地代码对应的JNI接口,这样Java代码就能够调用本地功能。
  • 加载本地库: 在Java代码中使用System.loadLibrary("libraryName")加载本地库。
  • 调用本地功能: 通过JNI接口调用本地代码,执行相应的功能。
  • 资源管理: 注意JNI中需要管理内存和资源,防止内存泄漏和资源泄漏。


需要注意的是,使用JNI涉及到一些底层的编程技巧,以及对内存管理、线程安全等问题的处理。不当的使用可能会导致性能问题和安全隐患。

2 基本概念描述

2.1 基本数据类型

JNI 对于 Java 的基础数据类型(int 等)和引用数据类型(Object、Class、数组等)的处理方式不同。这个原理非常重要,理解这个原理才能理解后面所有 JNI 函数的设计思路:

基础数据类型: 会直接转换为 C/C++ 的基础数据类型,例如 int 类型映射为 jint 类型。由于 jint 是 C/C++ 类型,所以可以直接当作普通 C/C++ 变量使用,而不需要依赖 JNIEnv 环境对象;


引用数据类型: 对象只会转换为一个 C/C++ 指针,例如 Object 类型映射为 jobject 类型。由于指针指向 Java 虚拟机内部的数据结构,所以不可能直接在 C/C++ 代码中操作对象,而是需要依赖 JNIEnv 环境对象。另外,为了避免对象在使用时突然被回收,在本地方法返回前,虚拟机会固定(pin)对象,阻止其 GC。(参考demo中的multipleArray函数实现)


另外需要特别注意一点,基础数据类型在映射时是直接映射,而不会发生数据格式转换。例如,Java char 类型在映射为 jchar 后旧是保持 Java 层的样子,数据长度依旧是 2 个字节,而字符编码依旧是 UNT-16 编码。

以下为Java类型与JNI类型的映射关系表,C++开发人员需要特别注意表中byte与char的区别。

Java类型 JNI类型 描述 长度(字节)
boolean jboolean unsinged char 1
byte jbyte signed char 1
char jchar unsinged short 2
short jshort signed short 2
int jint, jsize signed int 4
long jlong signed long 8
float jfloat signed float 4
double jdouble signed double 8
Class jclass Class类 /
String jstring 字符串类 /
Object jobject 所有java类的父类 /
Throwable jthrowable 异常对象 /
boolean[] jbooleanArray 布尔数组 /
byte[] jbyteArray byte数组 /
char[] jcharArray char数组 /
short[]</
  • 19
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Chap1:JNI完全手册... 3 Chap2:JNI-百度百科... 11 Chap 3:javah命令帮助信息... 16 Chap 4:用javah产生一个.h文件... 17 Chap5:jni教程(very very good) 19 Chap6: JNI传递返回值... 26 15.2.2.3 传递字符串... 28 15.2.2.4 传递整型数组... 29 15.2.2.5 传递字符串数组... 30 15.2.2.6 传递对象数组... 31 Chap7:Jni中C++和Java的参数传递... 33 Chap8:如何将java传递过来的jbyteArray转换成C/C++中的BYTE数组... 47 Chap5:使用JNI技术实现java程序调用第三方dll(c/c++)文件的功能... 47 Chap9:如何编写jni方法(转载)... 55 1、实例一:在jni中调用标准c中自带的函数printf(): 57 2、实例二、调用c 语言用户定义的函数... 58 3、实例三、在jni函数中访问java类中的对象实例域... 58 4、实例四:在jni函数中访问类的静态实例域... 60 5、实例五:在jni函数中调用java对象的方法... 60 6、实例六:在jni函数中调用java类的静态方法... 61 7、实例七:jni函数中传递基本数据类型参数... 62 8、实例八:在jni函数中传递对象类型参数... 62 9、实例九:在jni函数中处理字符串... 63 10、实例十:在jni函数中处理数组... 64 11、实例十一:在jni中的返回值问题... 65 12、实例十二:在jni中创建java类对象:... 66 Chap10:在 Windows 中实现 Java 本地方法... 66 1.Java 调用 C. 67 2.调试... 76 3.其他信息... 79 Chap11:如何在C/C++中调用Java. 80 1.环境搭建... 81 2.初始化虚拟机... 83 3.访问类方法... 85 4访问类属性... 87 5.访问构造函数... 88 6.数组处理... 89 7.中文处理... 89 8.异常... 91 9.线程和同步访问... 91 10.时间... 92 Chap12:基本JNI调用技术(c/c++与java互调) 93 Chap13:JNI的c代码中,另外一个线程获取 JNIEnv. 96 chap 14:当JNI遇到多线程--java对象如何被C++中的多个线程访问?. 97 chap 15:JNI在多线程中的应用... 101 chap 16:JNI限制(多线程)... 105 chap 17:使用 Java Native Interface 的最佳实践... 106 1.性能缺陷... 107 2.正确性缺陷... 117 3.避免常见缺陷... 121 4.结束语... 128 Chap18:JNI设计实践之路... 129 一、 前言... 129 二、 JNI基础知识简介... 130 三、 Java程序调用非Java程序... 131 四、 C/C++访问Java成员变量和成员方法... 138 五、 异常处理... 140 六、 MFC程序中嵌入Java虚拟机... 142 Chap19:JNI编程系列之基础篇... 148 System.loadLibrary("HelloWorld"); 149 JNIEXPORT void JNICALL Java_HelloWorld_print (JNIEnv *, jobject); 150 Chap20:JNI编程系列之中级篇(上)... 151 1. Java基本类型的传递... 151 2. String参数的传递... 151 3. 数组类型的传递... 153 4. 二维数组和String数组... 154 Chap21:JNI编程系列之高级篇... 155 1. 在一般的Java类中定义native方法... 156 2. 访问Java类的域和方法... 156 3. 在native方法使用用户定义的类... 157 4. 异常处理... 158
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值