今天在看代码的时候,发现文件中使用了native修饰的方法,本来想跟踪进去看一看的,发现并不可以,通过查资料才发现,使用native修饰的方法是调用本地方法,也就是本地使用C/C++编写的库函数,今天就来总结一下我的一些学习心得和在实践过程中遇到的问题。
native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中。Java语言本身不能对操作系统底层进行访问和操作,但是可以通过JNI接口调用其他语言来实现对底层的访问。总而言之:
- native 是用做java 和其他语言(如c++)进行协作时使用的,也就是native 后的函数的实现不是用java写的。
- 既然都不是java,那就别管它的源代码了,我们只需要知道这个方法已经被实现即可。
- native的意思就是通知操作系统, 这个函数你必须给我实现,因为我要使用。 所以native关键字的函数都是操作系统实现的, java只能调用。
- java是跨平台的语言,既然是跨了平台,所付出的代价就是牺牲一些对底层的控制,而java要实现对底层的控制,就需要一些其他语言的帮助,这个就是native的作用了
native方法是通过java中的JNI实现的。JNI是Java Native Interface的 缩写。从Java 1.1开始,Java Native Interface (JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计 的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的,比如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。JNI标准至少保证本地代码能工作在任何Java 虚拟机实现下。
JNI的开发步骤:
1.编写带有native声明的方法的java类,生成*.java文件
2.使用javac命令编译所编写的java类,生成.class文件
3.使用javah -jni java类名(第一步生成的) 生成扩展名为h的头文件,也就生成.h文件
4.使用C/C++(或其他编程语言)实现本地方法,创建.h文件的实现,也就是创建.cpp文件实现.h文件中的方法
5.将C/C++编写的文件生成动态链接库,即生成dll文件
JNI开发实例:
1.编写带有native声明的方法的java类
<span style="font-size:18px;">public class HelloWorld{
public native void displayHelloWorld();
static{
System.loadLibrary("HelloWorldImpl");
//装入动态链接库,“HelloWorldIdImpl”是要装入的动态链接库名称
}
public static void main(String[] args){
HelloWorld helloworld=new HelloWorld();
helloworld.displayHelloWorld();
}
}</span>
首先,打开命令窗口,开始->运行->cmd,切换到你的java文件所在目录
然后运行命令:javac HelloWorld.java,在本文件夹下生成.class文件
然后继续输入:javah -jni HelloWorld,生成HelloWorld.h文件
3.打开HelloWorld.h文件,内容如下:
<span style="font-size:18px;">/* 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: displayHelloWorld
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif</span>
可以看到我们定义的displayHelloWorld,在此处生成了方法Java_HelloWorld_displayHelloWorld(JNIEnv *,jobject)
4.新建一个.cpp文件实现上面的方法(我使用的是Visual Studio 2010版本)
注意:新建的cpp文件名称要和我们在第一步中System.loadLibrary("HelloWorldImpl")设置的名称一致
新建过程如下:点击新建->项目
编写HelloWorldImpl.cpp文件:
#include"HelloWorld.h"
#include<stdio.h>
#include"jni.h"
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *, jobject){
printf("Hello World,this method written by C++\n");
return ;
}
生成动态链接库:
A.将HelloWorldImpl.cpp文件拷贝到java文件同一级目录下
B.然后找到你的jdk安装目录\include文件夹,我的安装路径是:D:\program files(X86)\Java\jdk\include
C.将D:\program files(X86)\Java\jdk\include\jni.h;D:\program files(X86)\Java\jdk\include\win32\jawt_md.h和 jni_md.h拷贝到你的Visual Studio\VC\include文件夹下
我的路径是:D:\program files(X86)\Visual Studio2010\Micro Visual Studio\VC\include
D.打开visual Studio 命令提示
打开之后,运行以下命令:
可以看到我们编译成功啦!打开我们的Visual Studio/VC文件夹,可以看到我们生成的文件
提示:这一步中可能会出现以下错误提示:
原因分析:
没有把jni.h文件拷贝到Visual Studio\include文件,拷贝过来之后,就可以正常显示了。
然后将HelloWorldImpl.dll文件拷贝到原来创建java文件的文件夹下,然后去命令行界面运行文件HelloWorld.class文件
运行结果如上所示。
over~~~