【Java的JNI快速学习教程】

1. JNI简介



  JNI是Java Native Interface的英文缩写,意为Java本地接口。

  问题来源:由于Java编写底层的应用较难实现,在一些实时性要求非常高的部分Java较难胜任(实时性要求高的地方目前还未涉及,实时性这类话题有待考究)。

  解决办法:Java使用JNI可以调用现有的本地库(C/C++开发任何和系统相关的程序和类库),极大地灵活Java的开发。

2. JNI快速学习教程



2.1 问题:

  使用JNI写一段代码,实现string_Java_Test_helloworld(JNIEnv *env, jclass cls , jstring j_str)函数,实现在字符串j_str("world")前面加上hello,并返回。

2.2 解决问题过程:

  I. 编写Test.java类:

 1 public class Test{
 2     // native interface
 3     public native String helloworld(String text);
 4
 5     public static void main(String[] args){
 6         // Load dynamic library
 7         System.loadLibrary("Test2");
 8         Test ts = new Test();
 9         String text = ts.helloworld("world");
10         System.out.println(text);
11     }
12 }

  备注:

    1、加载动态类库:System.loadLibrary("Test2");【Windows下加载的就是Test2.dll,Linux下加载的是Test2.so】

  II. 编译Test.java文件

    进入cmd输入命令 > javac Test.java

  III. 生成Test.h文件

    进入cmd输入命令 > javah Test

  Test.h文件内容如下:

 1 /* DO NOT EDIT THIS FILE - it is machine generated */
 2 #include <jni.h>
 3 /* Header for class Test */
 4
 5 #ifndef _Included_Test
 6 #define _Included_Test
 7 #ifdef __cplusplus
 8 extern "C" {
 9 #endif
10 /*
11  * Class:     Test
12  * Method:    helloworld
13  * Signature: (Ljava/lang/String;)Ljava/lang/String;
14  */
15 JNIEXPORT jstring JNICALL Java_Test_helloworld
16   (JNIEnv *, jobject, jstring);
17
18 #ifdef __cplusplus
19 }
20 #endif
21 #endif

  备注:

    1、函数声明,固定格式:JNIEXPORT;返回类型:jstring;JNI调用:JNICALL;Java_完整类名_方法名:Java_Test_helloworld;

    2、函数参数:调用jni.h封装好的函数指针:JNIEnv;Java类本身:jobject,Java文件传入参数:jstring。

  IV. 编写C语言文件Test2.c实现Test类调用动态链接库的功能:

 1 #include "Test.h"
 2 #include <string.h>
 3
 4 JNIEXPORT jstring JNICALL Java_Test_helloworld
 5   (JNIEnv *env, jobject obj, jstring string){
 6     const char* str = (*env)->GetStringUTFChars(env,string,0);
 7     char cap[128];
 8     cap[0] = ‘h‘;
 9     cap[1] = ‘e‘;
10     cap[2] = ‘l‘;
11     cap[3] = ‘l‘;
12     cap[4] = ‘o‘;
13
14     strcat(cap,str);
15
16     (*env)->ReleaseStringUTFChars(env,string,0);
17     return (*env)->NewStringUTF(env,cap);
18   }

  备注:

    1、由于Java本身使用了双字节字符,C语言本身都是单字节字符,所以需要使用(*env)->GetStringUTFChars()转换Java和C之间的字符串;

    2、GetStringUTFChars()和NewStringUTF(),第一个是从UTF8转换为C的编码格式,第二个是根据C的字符串返回一个UTF8字符串;

    3、ReleaseStringUTFChars()是用来释放对象的,在Java中有虚拟机进行垃圾回收,但是在C语言中这些对象必须手动回收,否则可能造成内存泄漏。

  V. 编译和运行

  编译:

    进入cmd输入命令 > gcc -I "D:\Program Files\Java\jdk1.8.0_45\include" -I "D:\Program Files\Java\jdk1.8.0_45\include\win32" --share Test2.c -o Test2.dll

  运行:

    进入cmd输入命令 > java Test

  运行结果如下:

    helloworld

3. 总结:



  第一步:编写带有native方法的Java类(Test.java),使用javac工具编译Java类(生成Test.class);

  第二步:使用javah生成与native方法对应的头文件(Test.h);

  第三步:使用C/C++实现相应的头文件(Test2.c),并编译为动态链接库(Test2.so)。

  本文运行环境:Windows 64位操作系统,JDK 1.8版本,mingw64(GCC)。

4. 参考:



  http://www.cnblogs.com/icejoywoo/archive/2012/02/22/2363709.html

 【转载本文章请备注原地址出处:http://www.cnblogs.com/eesijian/p/5843879.html 】

时间: 2024-10-26 10:03:26

【Java的JNI快速学习教程】的相关文章

【Java线程池快速学习教程】

1. Java线程池 线程池:顾名思义,用一个池子装载多个线程,使用池子去管理多个线程. 问题来源:应用大量通过new Thread()方法创建执行时间短的线程,较大的消耗系统资源并且系统的响应速度变慢.[在一个什么程度上能够判断启用线程池对系统的资源消耗比启动定量的new Thread()资源消耗低?这个怎么测试?][用户体验卡顿?慢?观察CPU百分比?] 解决办法:使用线程池管理短时间执行完毕的大量线程,通过重用已存在的线程,降低线程创建和销毁造成的消耗,提高系统响应速度. 2. Java线

【Java,JNI】学习汇总

START FROM 2014/5/12 for memory of wenchuan [1]关于java内存的三篇文章: 1,内存模型http://www.cnblogs.com/aigongsi/archive/2012/04/26/2470296.html 而内存模型就是规定了一个规则,处理器如何同主内存同步数据的一个规则. 2,垃圾回收http://www.cnblogs.com/aigongsi/archive/2012/04/06/2434771.html 要点:jvm采用找root

Maven快速学习教程

〇.为什么要Maven 在开发中经常需要依赖第三方的包,包与包之间存在依赖关系,版本间还有兼容性问题,有时还里要将旧的包升级或降级,当项目复杂到一定程度时包管理变得非常重要. Maven是当前最受欢迎的Java项目管理构建自动化综合工具,类似以前Java中的Ant.node.js中的npm.dotNet中的nuget.PHP中的Composer. Maven这个单词来自于意第绪语(犹太语),意为知识的积累. Maven提供了开发人员构建一个完整的生命周期框架.开发团队可以自动完成项目的基础工具建

Java核心编程快速学习

Java核心编程部分的基础学习内容就不一一介绍了,本文的重点是JAVA中相对复杂的一些概念,主体内容如下图所示. 反射reflect是理解Java语言工作原理的基础,Java编译器首先需要将我们编写的.java源文件编译为.class字节码,然后再JVM虚拟机上运行,接下来通过一个表格,来了解反射的基本操作. 功能 示例 泛化的Class引用 Class<?> intClass = int.class Class<? extends Number> bounded = int.cl

MATLAB数据处理快速学习教程

转自:http://blog.csdn.net/abcjennifer/article/details/7706581 本篇内容集合了MATLAB中的基本操作.数据存储与计算.数据的直线与曲线拟合与画图.for-if-while语句的使用方法对一般matlab的操作进行了基本和详细的应用举例,非常适合初学者进行matlab学习快速掌握.下面分四个模块分别进行讲述: ========================BasicOperations======================== >>

java正则表达式最简单 学习教程

本大教程以一个验证手机号的表达式为例,学完本例后,基本上所有的表达式都能看懂了,但是如果想要达到上手就能写的程度,还需要多练习多测试 呀! 来看 这样一个代码 String mobilePhoneReg = "^((13[0-9])|(15[^4,\\D])|(18[0,0-9]))\\d{8}$"; if (!mobilephone.matches(mobilePhoneReg)) { showToast("手机号码格式不正确!"); return false;

【Android运行时权限申请快速学习教程】

1. Android权限介绍 Android权限是Android应用在设备上运行所需要的权力,义务就是为用户带来此Android应用的功能. 问题来源:在Android6.0版本之前,根据App在AndroidManifest申请的权限,在安装此App的时候进行提示权限允许,不允许就不给装不给用,那么我们只能默默的忍受这个APP对我们隐私的侵蚀(Eg.通讯录的读取权限). 解决办法:后来Google发现,诶,这样会导致Android用户们想用这个APP的某些功能而不能用.因此,在Android6

MongoDb 学习教程

MongoDB教程首页 MongoDB 介绍 MongoDB 优点 MongoDB 安装(Window/Linux) MongoDB 数据模型 MongoDB 创建数据库 MongoDB 删除数据库 MongoDB 创建集合 MongoDB 删除集合 MongoDB 数据类型 MongoDB 插入文档 MongoDB 查询文档 MongoDB 更新文档 MongoDB 删除文档 MongoDB 投影 MongoDB 限制记录 MongoDB 排序文档 MongoDB 索引 MongoDB 聚合

NetBeans工具学习之道:NetBeans IDE Java 快速入门教程

欢迎使用 NetBeans IDE! 本教程通过指导您创建一个简单的 "Hello World" Java 控制台应用程序,简要介绍 NetBeans IDE 工作流.学习完本教程后,您将对如何在 IDE 中创建和运行应用程序有一个基本了解. 学习完本教程所需的时间不到 10 分钟. 学完本教程后,您可以转至文档.培训和支持页中链接的学习资源.这些学习资源提供了综合性教程,其中重点介绍适用各种应用程序类型的更多 IDE 功能和编程技巧.如果您不希望创建 "Hello Worl