较详细的JNI简介

 更新时间:2017年10月18日 10:29:55   作者:动力节点  
JNI是本地语言编程接口。它允许运行在JVM中的Java代码和用C、C++或汇编写的本地代码相互操作。下面通过本文给大家分享JNI简介,感兴趣的朋友一起看看吧

在Java中,有时候我们不得不要去使用其他语言的代码,比如说:

1、你的应用需要访问系统的各个特性和设备,这些特性和设备通过java平台是无法访问的。

2、你已经有了大量的测试过和调试过的用另一种语言编写的代码,并且知道如何将其导出到所有的目标平台上。

3、通过基础测试,你已经发现所编写的Java代码比用其他语言编写的等价代码要慢得多。

Java平台有一个用于和本地C代码进行互操作的API,称为Java本地接口(JNI)。现在就开始学习JNI,先从这篇的一个最简单的例子,了解如何使用JNI调用本地方法。

调用本地方法,打印出HelloWorld的步骤示例

1、在类中声明一个本地方法

package com.tao.test; 
public class NativeTest { 
 public static native void sayHello(); 
} 

我们使用native关键字,声明了一个本地方法,而且我们还将他声明为static。本地方法可以是静态的,也可以不声明为静态的。

2、编译.java文件,生成 含有该本地方法的类的字节码

如果是在eclipse中,进入<工程目录>\bin\com\tao\test,就可以找到eclipse自动为我们编译的.class文件。

如果不是,则进入进入NativeTest.java文件所在的目录,使用javac命令编译该java类,生成了NativeTest.class字节码。

3、使用javah命令编译.class字节码,生成包含native方法声明的C/C++头文件

如果是在eclipse中,进入<工程目录>\bin目录,然后使用下面的编译命令(如果不是eclipse,则根据上面编译生成的.class文件的位置来用javap编译)

1.javah com.tao.test.NativeTest   //记住要使用类型的全限定名称  

就会在bin目录下,生成我们需要的C\C++头文件   com_tao_test_NativeTest.h (头文件的名字带包名,且用_ 分隔),里面内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */ 
#include <jni.h> 
/* Header for class com_tao_test_NativeTest */ 
 
#ifndef _Included_com_tao_test_NativeTest 
#define _Included_com_tao_test_NativeTest 
#ifdef __cplusplus 
extern "C" { 
#endif 
/* 
 * Class:  com_tao_test_NativeTest 
 * Method: sayHello 
 * Signature: ()V 
 */ 
JNIEXPORT void JNICALL Java_com_tao_test_NativeTest_sayHello 
 (JNIEnv *, jobject); 
 
#ifdef __cplusplus 
} 
#endif 
#endif 

4、按照生成的C/C++头文件来写C/C++源文件,并编译为DLL动态链接库

我们之前得到了包含native方法声明的C/C++头文件,现在我们按照这个头文件,编写我们的C\C++源文件,并编译为DLL动态链接库。

上一步,我们得到了com_tao_test_NativeTest.h头文件。

①、首先。新建一个Win32 DLL项目(我使用的是VS2005开发环境,VC6.0++是新建一个Win32 Dynamic-Link Library)

    新建——>项目——>Visual C++——>Win32——>控制台应用程序——>输入项目名称,我使用为NativeCall

点击确定后,进入下面的界面

点击下一步,进入下一界面,勾选为DLL和空项目。

这样就建立了一个Win32 DLL项目了。

②、添加com_tao_test_NativeTest.h头文件

将com_tao_test_NativeTest.h头文件复制,黏贴到NativeCall/NativeCall/目录下,如E:\VCProject\NativeCall\NativeCall该文件夹。然后再VS2005中的项目中,添加该头文件

③、添加jni.h和

打开com_tao_test_NativeTest.h头文件,看第二行,调用了 jni.h,这个头文件需要我们自己添加,为了JAVA_HOME/include目录下,添加方式和第②步一样

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

然后把上面的第二行的 #include <jni.h>改为#include “jni.h“。让它去调用我们自己的头文件,而不是系统的头文件。

打开jni.h,我们可以找打这么一行

1.#include "jni_md.h"  

这个头文件也要我们自己添加,它位于JAVA_HOME/include/win32目录中,添加方式和前面一致。

④、编写源文件。

新建一个源文件,命名为NativeMethod

然后,在里面添加下面代码:

#include "com_tao_test_NativeTest.h" //引入头文件 
#include <iostream> 
using namespace std; 
 JNIEXPORT void JNICALL Java_com_tao_test_NativeTest_sayHello //本地方法的实现 
(JNIEnv * env, jobject obj) 
{ 
 cout<<"hello World!"<<endl; 
} 

最后,保存,运行,编译生成DLL文件,在工程项目的Debug目录中可以找到。

5、将DLL文件放入到PATH环境变量下。

复制DLL文件所在路径,加入到PATH环境变量下。

6、在java中调用我们这个本地方法

public class NativeTest { 
 static{ 
  System.loadLibrary("NativeCode"); 
 } 
 public native void sayHello(); 
 public static void main(String[] args) { 
  new NativeTest().sayHello(); 
 } 
} 

注意:

1、一般在static代码块中加载动态链接库

2、如果将DLL路径加入PATH环境变量的时候,eclipse是开着的,那么要关闭eclipse再开,让eclipse重新读取环境变量

3、必须在本类中使用native方法

下图表示了我们编写JNI的过程

总结

以上所述是小编给大家介绍的较详细的JNI简介,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

相关文章

  • 浅谈Java类的加载,链接及初始化

    浅谈Java类的加载,链接及初始化

    今天给大家带来的是关于Java的相关知识,文章围绕着Java类的加载,链接及初始化展开,文中有非常详细的解释及代码示例,需要的朋友可以参考下
    2021-06-06
  • java中Optional的使用详细解析

    java中Optional的使用详细解析

    这篇文章主要介绍了java新特性之Optional的详细解析,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下
    2021-04-04
  • 基于JavaSwing+mysql开发一个学生社团管理系统设计和实现

    基于JavaSwing+mysql开发一个学生社团管理系统设计和实现

    项目使用Java swing+mysql开发,可实现基础数据维护、用户登录注册、社团信息列表查看、社团信息添加、社团信息修改、社团信息删除以及退出注销等功能、界面设计比较简单易学、适合作为Java课设设计以及学习技术使用,需要的朋友参考下吧
    2021-08-08
  • java FileWriter 追加文件及文件改名方式

    java FileWriter 追加文件及文件改名方式

    这篇文章主要介绍了java FileWriter 追加文件及文件改名的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • java实现构造无限层级树形菜单

    java实现构造无限层级树形菜单

    这篇文章主要介绍了java实现构造无限层级树形菜单,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • SpringBoot+Mybatis+Vue 实现商品模块的crud操作

    SpringBoot+Mybatis+Vue 实现商品模块的crud操作

    这篇文章主要介绍了SpringBoot+Mybatis+Vue 实现商品模块的crud操作,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • 举例讲解Java设计模式编程中模板方法模式的运用实例

    举例讲解Java设计模式编程中模板方法模式的运用实例

    这篇文章主要介绍了Java设计模式编程中模板方法模式的运用实例,模板方法模式强调基于继承的代码复用,需要的朋友可以参考下
    2016-05-05
  • springboot添加AOP日志配置详解

    springboot添加AOP日志配置详解

    这篇文章主要介绍了springboot添加AOP日志配置详解,日志是一种在软件开发中常用的技术,用于记录和跟踪应用程序的运行过程,通过AOP日志,开发人员可以实时监控应用程序的行为,包括方法的调用、参数的传递和返回值的获取等,需要的朋友可以参考下
    2023-10-10
  • Eclipse新建web项目流程图解

    Eclipse新建web项目流程图解

    这篇文章主要介绍了Eclipse新建web项目流程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11
  • java编程调用存储过程中得到新增记录id号的实现方法

    java编程调用存储过程中得到新增记录id号的实现方法

    这篇文章主要介绍了java编程调用存储过程中得到新增记录id号的实现方法,涉及Java数据库操作中存储过程的相关使用技巧,需要的朋友可以参考下
    2015-10-10

最新评论