码迷,mamicode.com
首页 > 编程语言 > 详细

【java】详解native方法的使用

时间:2017-07-24 09:56:03      阅读:634      评论:0      收藏:0      [点我收藏+]

标签:include   ide   function   style   libary   路径   查询   src   margin   

目录结构:

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!。

3,参考文章

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

 

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

【java】详解native方法的使用

标签:include   ide   function   style   libary   路径   查询   src   margin   

原文地址:http://www.cnblogs.com/HDK2016/p/7226840.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!