目录结构:

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. 使用canvas实现一个圆球的触壁反弹

    HTML <canvas id="canvas" width="500" height="500" style="borde ...

  2. 深入理解USB流量数据包的抓取与分析

    0x01 问题提出 在一次演练中,我们通过wireshark抓取了一个如下的数据包,我们如何对其进行分析? 0x02 问题分析 流量包是如何捕获的? 首先我们从上面的数据包分析可以知道,这是个USB的 ...

  3. python基础学习笔记(一)

    安装与运行交互式解释器 在绝大多数linux和 UNIX系统安装中(包括Mac OS X),Python的解释器就已经存在了.我们可以在提示符下输入python命令进行验证(作者环境ubuntu) f ...

  4. C++ string简单的使用技巧

    截取substr //string的操作 #include<iostream> using namespace std; int main() { string a,b; a=" ...

  5. 作业20171102 beta1 成绩

    申诉 对成绩有疑问或不同意见的同学,请在群里[@杨贵福]. 申诉时间截止2017年12月12日 17:00. 成绩 scrum01 scrum02 scrum03 scrum04 scrum05 sc ...

  6. M2事后会议报告

    设想和目标 1. 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? Beta阶段的爬虫需要更稳定.更高效.操作更便捷.在定义中爬取对性能和功能的要求高,典型用户和场景 ...

  7. Linux实验四报告

    张文俊 + 原创作品转载请注明出处+ <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.学习内容 系统 ...

  8. This Android SDK requires Android Developer Toolkit version 17.0.0 or above. Current version is 10.0.0.v201102162101-104271. Please update ADT to the latest version.

    win7/xp 下面安装Android虚拟机,更新SDK后,在Eclipse preference里指向android-sdk-windows时. 出现 : This Android SDK requ ...

  9. Leetcode——66.加一

    @author: ZZQ @software: PyCharm @file: leetcode66_加一.py @time: 2018/11/29 16:07 要求:给定一个由整数组成的非空数组所表示 ...

  10. java — 静态绑定和动态绑定

    绑定:一个方法的调用与方法所在的类关联起来.java中的绑定分为静态绑定和动态绑定,又被称作前期绑定和后期绑定. 静态绑定:(final.static.private)在程序执行前已经被绑定,也就是说 ...