标签:style blog http color io os 使用 ar java
今天在看java关于调用本机代码子程序来获得较快的执行时间,或者,你希望用一个专用的第三方的库,例如统计学包。然而,因为Java程序被编译为字节码,字节码有Java运行时系统解释(或动态编译),看起来在Java程序中调用本机代码子程序是不可能。幸运的是,这个结论是错误的。Java提供了native关键字,该关键字用来声明本机代码方法。一旦声明,这些方法可以在Java程序中被调用,就像调用其他Java方法一样。
既然Java提供了native方法,那么如何实现呢?native是与C++联合开发的时候用的!使用native关键字说明这个方法是原生函数,也就是这个方法是用C/C++语言实现的,并且被编译成了DLL,由Java调用。这些函数的实现体在DLL中,JDK的源码中并不包含,你应该是看不到的。对于不同的平台它们也是不同的。这也是java的底层机制,实际上java就是在不同的平台上调用不同的native方法实现对操作系统的访问的。总而言之:
native方法是通过java中的JNI实现的。JNI是Java Native Interface的缩写。从Java1.1开始,Java Native Interface(JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受到支持就可以了。使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的,比如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。JNI标准至少保证本地代码能工作在任何Java虚拟机实现下。
目前java与dll交互的技术主要有三种:jni、jawin和jacob。JNI(Java Native Interface)是sun提供的java与系统中的原生方法交互的技术(在windows\linux系统中,实现java与native method互调)。目前只能由C/C++实现。后两个都是sourceforge上的开源项目,同时也都是基于JNI技术的windows系统上的应用库。Jacob(Java-ComBridge)提供了java程序调用microsoft的com对象中的方法的能力。而除了com对象外,jawin(Java/Win32 integration project)还可以win32-dll动态链接库中的方法。就功能而言:JIN>>jawin>jacob.就易用性而言,正好相反:jacob>jawin>>JNI
JVM封装了各种操作系统实际的差异性的同时,提供了JNI技术,使得开发者可以通过java程序(代码)调用到操作系统相关的技术实现的函数,从而与其他技术和系统交互,使用其他技术实现的功能;同时其他技术和系统也可以通过jni提供的相应原生接口调用java应用系统内部实现的功能。
在windows系统上,一般可执行的应用程序都是基于native的PE结构,windows上的jvm也是基于native结构实现的。Java应用体系都是构建与jvm之上。
JNI对于应用本身来说,可以看做一个代理模式。对于开发者来说,需要使用C/C++来实现一个的代理程序(jni程序)来实际操作目标原生函数,java程序中则是JVM通过加载并调用此JNI程序来间接地调用目标原生函数。
下列是所有操作都在目录:D:\Native下进行的,这样做的好处是便于控制。还有另外一个要求是我们的java类不含包名。不然在使用javah -jni class文件名会提示错误:找不到‘class’的类文件。
public class NativeDemo { int i; public static void main(String[] args) { NativeDemo ob=new NativeDemo(); ob.i=10; System.out.println("This is ob.i before the native method:"+ ob.i); ob.test();//call a native method. System.out.println("This is ob.i after the native method:"+ ob.i); } //declare native method public native void test(); //load DLL that contains static method static{ System.loadLibrary("NativeDemo"); } }
在编写的Java类时候,一定要注意不要带包名。尤其用eclipse时候自动添加包名。
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class NativeDemo */ #ifndef _Included_NativeDemo #define _Included_NativeDemo #ifdef __cplusplus extern "C" { #endif /* * Class: NativeDemo * Method: test * Signature: ()V */ JNIEXPORT void JNICALL Java_NativeDemo_test (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
这个h文件相当于我们在java里面的接口,这里声明了一个Java_NativeDemo_test(JNIEnv *, jobject).方法,然后在我们的 本地方法里面实现这个方法,也就是说我们在编写C/C++程序的时候所使用的方法名必须和这里一致。
*This file contains the C version of the test() method*/ #include<jni.h> #include "NativeDemo.h" #include <stdio.h> JNIEXPORT void JNICALL Java_NativeDemo_test(JNIEnv *env,jobject obj) { jclass cls; jfieldID fid; jint i; printf("Starting the native method.\n"); cls=(*env)->GetObjectClass(env, obj); fid=(*env)->GetFieldID(env, cls, "i","I"); if(fid==0){ printf("Could not get field id.\n"); return; } i=(*env)->GetIntField(env ,obj,fid); printf("i=%d\n",i); (*env)->SetIntField(env,obj,fid,2*i); printf("Ending the native method.\n"); }
如果你电脑是32操作系统,就选用红色方框进行编译,如果64位操作系统选择红色方框下面那个进行编译。具体操作如下:
执行完上述命令后,在D:\Program Files\Microsoft Visual Studio 10.0\VC可以看到生成的四个文件,分别是:
将其中的NativeDemo.dll拷贝到D:\Native\目录下。
7.执行class得到结果
在cmd中运行:在D:\Native\目录下:java NativeDemo 。运行结果如图所示。
标签:style blog http color io os 使用 ar java
原文地址:http://www.cnblogs.com/chuji1988/p/4005736.html