JNI(Java Native Interface)是SUN定义的一套标准接口,供本地(C/C++)应用与Java VM互调。因为C/C++在系统编程领域的地位,只要打通了与C/C++的接口就等于是天堑变通途。
使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的。例如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。
1. 编写带有native声明的方法的java类
2. 使用javac命令编译所编写的java类
3. 然后使用javah 生成扩展名为h的头文件
4. 使用C/C++实现本地方法
5. 将C/C++编写的文件生成动态连接库
6. java程序中调用该动态链接库完成应用。
下边一步步的完成,使用的工具有 jdk eclipse vc
1,在eclipse中新建java工程“JNIStudy”,创建包“com.study.jni”,创建NativeHello类。
package com.study.jni;
publicclass NativeHello { //声明native方法 publicnativevoid HelloWorld(String str); //加载hello动态链接库,这个在后边生成。 static { System.loadLibrary("hello"); }
}
|
声明native方法:如果你想将一个方法做为一个本地方法的话,那么你就必须声明该方法为native的,并且不能实现。
System.loadLibrary("hello");加载动态库,一般是以static块进行加载的,需要注意的是System.loadLibrary();的参数“hello”是动态库的名字。
2,由于eclipse中的文件是自动编译的,在项目中可以看到已经编译好的类文件。如果没有编译话需要手动编译。
3,下边需要手动生成头文件,通过在运行框中输入cmd打开命令行,
先输入项目所在的盘符,然后进入项目所在路径,输入以下命令,生成头文件。
Microsoft Windows XP [版本 5.1.2600] (C) 版权所有 1985-2001 Microsoft Corp.
C:\Documents and Settings\Administrator>d:
D:\>cd D:\workspace\JNIStudy\bin
D:\workspace\JNIStudy\bin>javah com.study.jni.NativeHello
D:\workspace\JNIStudy\bin> |
注意生成头文件的路径是在生成类文件的根目录(bin)下,这个文件中不要有中文,否则在生成头文件时不报错,但生成的文件内容不完全。
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_study_jni_NativeHello */
#ifndef _Included_com_study_jni_NativeHello #define _Included_com_study_jni_NativeHello #ifdef __cplusplus extern "C" { #endif /* * Class: com_study_jni_NativeHello * Method: HelloWorld * Signature: (Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_com_study_jni_NativeHello_HelloWorld (JNIEnv *, jobject, jstring);
#ifdef __cplusplus } #endif #endif |
4,在vc中新建动态链接库工程,工程名与刚才需要加载的一致hello
点击ok,然后创建一个空的dll项目。
5 新建文件hello.cpp,保存在项目的根目录下
然后输入内容
#include <jni.h> #include "com_study_jni_NativeHello.h"
JNIEXPORT void JNICALL Java_com_study_jni_NativeHello_HelloWorld(JNIEnv *env, jobject obj, jstring jstr) { const char* str = env->GetStringUTFChars(jstr,0); printf(str); env->ReleaseStringUTFChars(jstr,str); return; } |
然后把这个文件添加到vc项目中,
拷入上一步生成头文件和下边的头文件%JAVA_HOME%\include jni.h到VC项目的根目录下,同样的把文件添加到VC的项目中。注意是在头文件中加入。
如果幸运的话,可以如上图所示,如果有错误的,根据提示进行解决。
下边就可以在eclipse中使用这个本地方方法了。
6,编写调用文件,并加入生成动态链接库文件到项目中
package com.study.jni;
publicclass HelloWorld {
/** * @param args */ publicstaticvoid main(String[] args) { NativeHello nh=new NativeHello(); nh.HelloWorld("Hello native method !"); }
} |
如果这个动态链接库文件放的路径不对,将会引用不到而报错,
Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello in java.library.path
意思是说在这个环境变量中找不到这个引用。有很多办法解决。我的方法是通过eclipse的导入功能,把这个文件以文件的方式导入到项目中。
选择hello.dll文件,即可导入,导入成功后文件实际是放在项目的根目录下。
或者还可以通过查看System.out.println(System.getProperty("java.library.path"));的值来放到可以加载的地方。
终于完成!然后运行程序,就可以看到结果了
“I am loading the native method !”