目录结构:

contents structure [+]

1,关于native关键字

想必读者已经了解过native关键字了。这里笔者就大致囊括一下,被native关键字修饰的方法叫做本地方法,本地方法和其它方法不一样,本地方法意味着和平台有关,因此使用了native的程序可移植性都不太高。另外native方法在JVM中运行时数据区也和其它方法不一样,它有专门的本地方法栈。native方法主要用于加载文件和动态链接库,由于Java语言无法访问操作系统底层信息(比如:底层硬件设备等),这时候就需要借助C语言来完成了。被native修饰的方法可以被C语言重写。

2,使用native关键字

2.1,使用步骤

  • Java程序中声明native修饰的方法,类似于abstract修饰的方法,只有方法签名,没有方法实现。编译该java文件,会产生一个.class文件。
  • 使用javah编译上一步产生的class文件,会产生一个.h文件。
  • 写一个.cpp文件实现上一步中.h文件中的方法。
  • 将上一步的.cpp文件编译成动态链接库文件.dll。
  • 最后就可以使用System或是Runtime中的loadLibrary()方法加载上一步的产生的动态连接库文件了。

2.2,案例

为了更好理解,该案例的所有都在文件在 D:\JNI\ 目录下。

2.2.1 编写.java文件

public class HelloWorld{
public native void h();//该方法和abstract修饰的方法一样,只有签名。 static{
System.loadLibrary("hello");//不写文件的后缀,程序会自动加上.dll的。
} public static void main(String[] args){
new HelloWorld().h();//调用
}
}

HelloWorld.java

2.2.2 编译.java文件

在AMD中编译该程序 javac HelloWorld.java ,就会产生一个HelloWorld.class文件。

2.2.3 获得.h文件

将第二步中产生的字节码文件,通过 javah -jni HelloWorld 就会产生一个HelloWorld.h文件。

我们用记事本打开HelloWorld.h文件

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

可以看出,在HelloWorld.java文件中的h()方法已经变成了 JNIEXPORT void JNICALL Java_HelloWorld_h (JNIEnv *, jobject); ,方法名是原来的 包名_类名_方法名 。在该文件中还引用了 jni.h 文件。

2.2.4 编写hello.cpp文件

编写hello.cpp文件的方式有许多,可以利用Visual Studio软件,因为最后需要生成dll文件,因此在下载Visual Studio之前应该查一查版本是否能够生成自己电脑需要的dll版本(32位dll或64为dll)。这里读者下载的是vs2013,该版本既可以生成32的dll,由可以生成64位的dll。关于vs2013生成dll可以参考Visual Studio 2013生成64位dll

因为我们在第一步中调用的文件名称为hello,所以这里的.cpp文件必须为 hello.cpp 文件。这里笔者的文件如下:

// hello.cpp : 定义 DLL 应用程序的导出函数。
// #include "stdafx.h"
#include "HelloWorld.h" JNIEXPORT void JNICALL Java_HelloWorld_h(JNIEnv *, jobject) {
printf("Hello! ");//打印信息
}

可以看出引入了 HelloWorld.h 文件,所以hello.cpp 文件应该和 HelloWorld.h文件在同一个目录下面。如果读者现在编译hello.cpp文件会报错 “jni.h”: No such file or directory 。在 HelloWorld.h 文件中我们引入了 jni.h文件,所以也应该把 jni.h 文件放到同一级目录下面,关于这个文件和相关的文件读者可以到JDK的安装目录下面的include下面查找,更多信息可以查看JDk、JRE、JVM的关系。还应该把 HelloWorld.h 文件中的 #include <jni.h> 改为 #include "jni.h" 。最后生成 hello.dll 文件就可以了

2.2.5 部署hello.dll文件

我们使用了 System.loadLibary("hello"); 加载动态链接库,这个加载路径是按照java.libary.path进行查询的,读者可以根据System.getProperty("java.libary.path")验证,该路径就是环境变量中的path路径。网上有好多说直接把hello.dll仍在 C:\Windows\System32 路径下。不过笔者建议,先应该查看自己环境变量path的值,那么把hello.dll放到path中配置的第一个路径下。

2.2.6 运行HelloWorld.class文件

我们回到  D:/JNI  路径下,使用  java HelloWorld  就成功调用动态连接库了。

笔者的控制台上成功打印了hello!。笔者对这里加载的理解,就是利用反射机制,在运行的时候找到hello.dll文件并且解析,根据动态链接库中的文件名称创建出对象和方法,然后我们就可以利用对象调用方法了。上面的HelloWorld.java文件,创建动态链接库和调用方法都在同一个类中,这样的话一个只需要使用这个类的对象调用方法就可以通过编译和运行了。如果我们引入的是被人的.cpp文件,那么根据.cpp文件中的方法名,在需要的地方做适当调整就可以调用了。

3,参考文章

自己实现一个native方法的调用

本文为博主原创文章,转载请注明出处。

【java】详解native方法的使用的更多相关文章

  1. [一]class 文件浅析 .class文件格式详解 字段方法属性常量池字段 class文件属性表 数据类型 数据结构

    前言概述  本文旨在讲解class文件的整体结构信息,阅读本文后应该可以完整的了解class文件的格式以及各个部分的逻辑组成含义   class文件包含了java虚拟机指令集 和  符号表   以及若 ...

  2. Java 详解 JVM 工作原理和流程

    Java 详解 JVM 工作原理和流程 作为一名Java使用者,掌握JVM的体系结构也是必须的.说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Java ...

  3. Java中的native方法

    博客引用地址:Java中的native方法 今天花了两个小时把一份关于什么是Native Method的英文文章好好了读了一遍,以下是我依据原文的理解. 一. 什么是Native Method 简单地 ...

  4. 详解Vue 方法与事件处理器

      本篇文章主要介绍了详解Vue 方法与事件处理器 ,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 方法与事件处理器 方法处理器 可以用 v-on 指令监听 DOM 事件 ...

  5. 逆向工程生成的Mapper.xml以及*Example.java详解

    逆向工程生成的接口中的方法详解 在我上一篇的博客中讲解了如何使用Mybayis逆向工程针对单表自动生成mapper.java.mapper.xml.实体类,今天我们先针对mapper.java接口中的 ...

  6. (转)Java 详解 JVM 工作原理和流程

    作为一名Java使用者,掌握JVM的体系结构也是必须的.说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Java编程语言.Java类文件格式.Java虚 ...

  7. java中的native方法和修饰符(转)

    Java中的native修饰符 今天偶然看代码,发现别人有这样写的方法,并且jar里面有几个dll文件,比较奇怪,于是把代码打开,发现如下写法. public native String GSMMod ...

  8. (摘录)Java 详解 JVM 工作原理和流程

    作为一名Java使用者,掌握JVM的体系结构也是必须的. 说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Java编程语言.Java类文件格式.Java ...

  9. java 里面的 native 方法

    第一篇: 今天花了两个小时把一份关于什么是Native Method的英文文章好好了读了一遍,以下是我依据原文的理解. 一. 什么是Native Method   简单地讲,一个Native Meth ...

随机推荐

  1. 分布式监控系统Zabbix3.4-钉钉告警配置记录

    群机器人是钉钉群的高级扩展功能,群机器人可以将第三方服务的信息聚合到群聊中,实现自动化的信息同步.例如:通过聚合GitHub,GitLab等源码管理服务,实现源码更新同步:通过聚合Trello,JIR ...

  2. PAT甲级题解-1066. Root of AVL Tree (25)-AVL树模板题

    博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6803291.html特别不喜欢那些随便转载别人的原创文章又不给 ...

  3. sql server选取第m行到第n行的元组

    现在有一个表Questioin,主码是qid,要求选择第m行到第n行的元组 //方法一:效率最低 //错误:如果n<m,将选取前n条数据,如果n>=m,将选取从m+1开始的n条数据 sel ...

  4. 【个人博客作业II】代码复审结果

    [代码复审结果] General Does the code work? Does it perform its intended function, the logic is correct etc ...

  5. 《Linux内核设计与实现》第四章学习笔记

    <Linux内核设计与实现>第四章学习笔记           ——进程调度 姓名:王玮怡  学号:20135116 一.多任务 1.多任务操作系统的含义 多任务操作系统就是能同时并发地交 ...

  6. SSH框架开发蛋糕房管理系统之质量属性

    SSH框架开发蛋糕房管理系统之质量属性 我要开发的系统是基于ssh框架的蛋糕房管理系统.本系统前台提供的主要功能是在线预定蛋糕,本店管理员拥有最高权限,包括收银管理,设备管理,日常销售管理,蛋糕定制管 ...

  7. Android Studio 打包AAR和第三方静态库

    需求 现在有一个第三方库libstatic_add.a和对应的头文件static.h,要求封装一个Module,该Module依赖这个静态库,要求打包的Module包含该静态库. 方案 创建Andro ...

  8. Filter学习:项目第八阶段

      public interface Filter A filter is an object that performs filtering tasks on either the request ...

  9. MySQLi面向对象实践--insert、update、delete

    执行insert <?php $mysqli = new Mysqli(); $mysqli->connect("localhost","root" ...

  10. 记Git报错-refusing to merge unrelated histories

    记Git报错-refusing to merge unrelated histories   系统:win7 git版本: 2.16.2.windows.1 问题 1.本地初始化了git仓库,放了一些 ...