java native方法是指本地方法,当在方法中调用一些不是由java语言写的代码或者在方法中用java语言
直接操纵计算机硬件时要声明为native方法。
java中,通过JNI(Java Native Interface,java本地接口)来实现本地化。
Java无法直接访问到操作系统底层(如系统硬件等),为此Java使用native方法来扩展Java程序的功能。
可以将native方法比作Java程序同C程序的接口,其实现步骤:
1、在Java中声明native()方法,然后编译;
2、用javah产生一个.h文件;(如果是包里的类的话,应采用 javah com.xxx.Object 类似这样的方法,否则会出错(UnsatisfiedLinkError)
)
3、写一个.cpp文件实现native导出方法,其中需要包含第二步产生的.h文件(注意其中又包含了JDK带的jni.h文件);
4、将第三步的.cpp文件编译成动态链接库文件;
5、在Java中用System.loadLibrary()方法加载第四步产生的动态链接库文件,这个native()方法就可以在Java中被访问了。
首先写好JAVA文件
/*
* Created on 2005-12-19 Author shaoqi
*/
package com.hode.hodeframework.modelupdate;
public class CheckFile
{
public native void displayHelloWorld();
static
{
System.loadLibrary("test");
}
public static void main(String[] args)
{
new CheckFile().displayHelloWorld();
}
}
然后根据写好的文件编译成CLASS文件
然后在classes或bin之类的class根目录下执行javah -jni com.hode.hodeframework.modelupdate.CheckFile,
就会在根目录下得到一个com_hode_hodeframework_modelupdate_CheckFile.h的文件
然后根据头文件的内容编写com_hode_hodeframework_modelupdate_CheckFile.c文件
#include "CheckFile.h"
#include #include
JNIEXPORT void JNICALL Java_com_hode_hodeframework_modelupdate_CheckFile_displayHelloWorld(JNIEnv *env, jobject obj) {
printf("Hello world!\n");
return;
}
之后编译生成DLL文件如“test.dll”,名称与System.loadLibrary("test")中的名称一致
vc的编译方法:cl -I%java_home%\include -I%java_home%\include\win32 -LD com_hode_hodeframework_modelupdate_CheckFile.c -Fetest.dll
最后在运行时加参数-Djava.library.path=[dll存放的路径]
使用java与本地已编译的代码交互,通常会丧失平台可移植性。
如何使用JNI
步骤
在java程序中加入本地方法说明:public native void methodName(){};
产生本地方法的头文件:javah –jni ClassName
本地方法的实现与编译:在c中方法名为:Java_ ClassName _ methodName (JNIEnv *env, jobject obj,***)将头文件和(本地方法)实现文件编译成共享库文件
Java代码部分:
定义native方法----当程序中的方法实现是采用java以外的语言时,必须以native关键字说明;
加载共享库----System.loadLibrary(“libname”)方法可以实现共享库的加载,从而完成native方法在声明和实现之间的映射。(在类定义过程中,一般以static前缀来描述这一代码,从而隐式加载共享库,
例如:static { System.loadLibrary(“libname”; )};另外,libname和库文件名的对应关系是平台相关的,如在Solaris中为liblibname.so,而Windows系统中为libname.so )
为本地方法创建头文件:
语法----javah –jni class文件名;
目的----得出native方法的文件名,见(二。3),注意,比java中的native方法多两参数。
本地方法实现:
在c语言中,本地函数的写法如下: JNIEXPORT void JNICALL Java_ ClassName _ methodName (JNIEnv *env, jobject obj,***){}
c语言代码应该包含下述头文件:jni.h及由javah生成的头文件。
JAVA调用DLL简单小例子
这个小例子用JNI调用了VC++做的DLL动态库。
1、总体说明:
实现一个函数,传入整形数i,返回值i*i,这个函数做在DLL中,java将通过JNI调用这个函数,传入一个参数,得到返回值。
确定DLL的名称为calldll.dll,函数shanfei(int i)。
2、编写java程序javacall.java,如下:
public class javacall
{
static
{
System.loadLibrary("calldll");
}
public native static int shanfei(int i);
public static void main(String[] args)
{
javacall jc = new javacall();
int j;
j = jc.shanfei(4);
System.out.println(j);
}
}
3、编译
javac javacall.java
4、生成头文件
javah javacall
生成javacall.h文件
5、制作VC++动态库
建立新DLL工程,程序中添加:
#include "javacall.h"
JNIEXPORT jint JNICALL Java_javacall_shanfei (JNIEnv *, jclass, jint p)
{
int j = p*p;
return j;
}
别忘了将javacall.h复制到VC工程目录中,然后编译,如果编译说找不到jni.h文件,可以将jni.h复制到工程目录中,还可将javacall.h文件中的#include <jni.h>改为#include "jni.h",再编译。
6、java调用
将生成的calldll.dll文件复制到javacall.java所在的目录中,运行
java javacall,应该可以看到运行结果。</jni.h>