Java不是完美的,Java的不足除了体现在运行速度上要比传统的C++慢许多之外,Java无法直接访问到操作系统底层(如系统硬件等),为此Java使用native方法来扩展Java程序的功能。
可以将native方法比作Java程序同C程序的接口,其实现步骤:
1、在Java中声明native()方法,然后编译;
2、用javah产生一个.h文件;
3、写一个.cpp文件实现native导出方法,其中需要包含第二步产生的.h文件(注意其中又包含了JDK带的jni.h文件);
4、将第三步的.cpp文件编译成动态链接库文件;
5、在Java中用System.loadLibrary()方法加载第四步产生的动态链接库文件,这个native()方法就可以在Java中被访问了。
JAVA本地方法适用的情况
1.为了使用底层的主机平台的某个特性,而这个特性不能通过JAVA API访问
2.为了访问一个老的系统或者使用一个已有的库,而这个系统或这个库不是用JAVA编写的
3.为了加快程序的性能,而将一段时间敏感的代码作为本地方法实现。
首先写好JAVA文件
/**
* NativeMethod.java
*/
package org.edi.Ts;
/**
* @author Administrator
*
*/
public class NativeMethod {
public native void display(int i);
/**
* @param args
*/
static
{
System.loadLibrary("test0");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new NativeMethod().display(1);
}
}
编译成CLASS文件
javac -d . NativeMethod.java
在当前目录(我的当前路径是源文件所在路径)下执行:
javah -jni org.edi.Ts.NativeMethod
(org.edi.Ts.NativeMethod是NativeMethod类的完整限定名)
命令执行成功的话会生成一个org_edi_Ts_NativeMethod.h文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_edi_Ts_NativeMethod */
#ifndef _Included_org_edi_Ts_NativeMethod
#define _Included_org_edi_Ts_NativeMethod
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: org_edi_Ts_NativeMethod
* Method: display
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_org_edi_Ts_NativeMethod_display
(JNIEnv *, jobject, jint);
#ifdef __cplusplus
}
#endif
#endif
JNIEXPORT void JNICALL Java_org_edi_Ts_NativeMethod_display (JNIEnv *, jobject, jint);是native method的函数声明这个不能修改。
org_edi_Ts_NativeMethod.h里面的JNIEXPORT等是安装JRE时针对你当前系统的适配。我的在%java_home%/include/win32/jni_md.h里面:
/*
* Copyright (c) 1996, 1998, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
#ifndef _JAVASOFT_JNI_MD_H_
#define _JAVASOFT_JNI_MD_H_
#define JNIEXPORT __declspec(dllexport)
#define JNIIMPORT __declspec(dllimport)
#define JNICALL __stdcall
typedef long jint;
typedef __int64 jlong;
typedef signed char jbyte;
#endif /* !_JAVASOFT_JNI_MD_H_ */
然后就可以编写实现native method的源文件:
/*
*NativeMethod.c
*/
#include "NativeMethod.h"
JNIEXPORT void JNICALL Java_org_edi_Ts_NativeMethod_display(JNIEnv * env, jobject o, jint i)
{
printf("Hello world!%d\n", i);
return;
}
上面的"NativeMethod.h"实际就是“org_edi_Ts_NativeMethod.h”我只不过重命名了下(这个无关紧要)
接下来就要把 NativeMethod.c编译成DLL文件。用的是Microsoft的“CL”工具(安装过VC的话就会有)
cl /LD -I"%java_home%/include" -I"%java_home/include/win32%" NativeMethod.c -Fe"test.dll"
/LD表示我要创建DLL文件。/I 指定头文件搜索路径(这两个java的头文件路径有一些类型定义像JNICALL等等)
最后运行先前编译的类文件(NativeMethod)
java -Djava.library.path="DLL文件所在的路径" org.edi.Ts.NativeMethod
上面都没有问题的话输出: