本地方法

来源:互联网 发布:淘宝国际机票 编辑:程序博客网 时间:2024/05/01 21:39

java本地方法

用native修饰符修饰的方法是本地方法。native修饰符一般用来声明用其他语言书写方法体、并具体实现方法功能的特殊方法。这里的其他语言包括C、C++、Fortran、汇编语言等。由于native方法的方法体是用其他语言在程序外部写成,所以所有的native方法都没有方法体,而用一个分号代替。
  为了支持native方法,Java提供了JNI软件工具,JNI是Java Native Interface的缩写。从Java 1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。
  用其他语言编写类方法的目的在于:充分利用已存在的程序功能模块,并避免重复工作。由于Java是解释型语言,它的运行速度不可能很快。在某些实时性比较强或执行效率要求比较高的场合,就可以利用native方法来求助于其他运行速度较高的语言。
  下面我们以一个例子,说明如何使用其他语言编写的程序,这里以C语言为例。

(1)编写java程序,在java程序中加入本地方法说明:

  public native void 方法名();

不妨仍然使用HelloWorld,如下所示。

  class HelloWorld { public native void displayHelloWorld(); static { System.loadLibrary("hello"); } public static void main(String[ ] args) { new HelloWorld().displayHelloWorld(); } }

这部分内容是选学内容,读者可以略去不看。
  在程序中,声明了一个displayHelloWorld的native方法,它是一个空方法;还利用静态初始化器加载了一个动态库(System.loadLibrary("hello");)。因为方法displayHelloWorld()并没有实现,但是在下面在main方法中就直接使用了,所以必须在使用前对它进行初始化。加载动态库就是实现这个目的,“hello”是动态库的名字。

(2)编译程序:

  javac HelloWorld.java

(3)生成扩展名为.h的头文件:

  javah –jni 类名

这里是:

  javah -jni HelloWorld

其中头文件HelloWorld.h的内容如下:

  /* DO NOT EDIT THIS FILE - it is machine generated */ #include /* 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

可以这样理解:这个.h文件相当于我们在java里面的接口,这里声明了一个Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject);方法,然后在我们的本地方法里面实现这个方法,也就是说我们在编写C/C++程序的时候所使用的方法名必须和这里的一致)。

(4)编写本地方法,实现和由javah命令生成的头文件里面声明的方法名相同的方法。本地方法在C语言中的方法名为:

  Java_ClassName _methodName (JNIEnv *env, jobject obj,……)

代码如下:

  #include "jni.h" #include "HelloWorld.h" #include JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj) { printf("Hello world!/n"); return; }

注意代码2中的第1行,需要将jni.h(该文件可以在%JAVA_HOME%/include文件夹下面找到)文件引入,因为在程序中的JNIEnv、jobject等类型都是在该头文件中定义的;另外在第2行需要将HelloWorld.h头文件引入。然后保存为HelloWorldImpl.c就可以了。

(5)将头文件和(本地方法)实现文件编译成共享库文件,生成动态库。
  这里以在Windows中为例,需要生成dll文件。在保存HelloWorldImpl.c文件夹下面,使用VC的编译器cl成:

  cl -I%java_home%/include -I%java_home%/include/win32 -LD HelloWorldImp.c -Fehello.dll

注意:生成的dll文件名在选项-Fe后面配置,这里是hello,因为在HelloWorld.java文件中我们loadLibary的时候使用的名字是hello。当然这里修改之后那里也需要修改。另外需要将-I%java_home%/include -I%java_home%/include/win32参数加上,因为在第四步里面编写本地方法的时候引入了jni.h文件。

(6)运行程序即可:

  java HelloWorld