- 概念
- JNI 即Java Native Interface
- JNI 是Java平台的一部分,通过他可以实现Java与其他语言交互(如 C C++)。
- JNI 是完善Java功能的一个重要功能。一方面JVM封装了操作系统的差异性,使Java可以跨平台。另一方面JNI提供了Java程序与操作系统相关功能函数交互的接口,不失Java功能的全面性。
- 应用场景
- 在程序对时间和性能敏感时,有必要用更底层的语言(如汇编 C C++)。
- 在已经有用其他语言写好的功能时,直接用Java调用。
- 在需要用到Java平台不具备的依赖于操作系统特性时。
- 原理
暂时没仔细研究原理。所以在此不好信口开河。
大致可以理解为,当调用native方法的时候JVM可以通过JNI调用本地方法的相应实现。
- 使用步骤
- 在Java类中定义native方法,并加载相应的动态库。 //产出.java
- javac -d . xxx.java 编译java源文件,得到.class和相应目录结构。 //产出.class
- javah -jni xxx 得到.h头文件。 //产出.h
- 编写本地方法实现和由javah命令生成的头文件里面声明的方法名相同的方法。 //产出.c / .cpp
- 通过相应IDE(集成开发环境 如vc) 和 .h .cpp 文件生成相应动态库 //产出 windows下为 .dll
- java xxx 运行Java类
- Demo
编写java源文件
Demo.java
package com.jiakai;
public class Demo {
static {
System.loadLibrary("test"); //加载相应动态库
}
public native void hello();
public static void main(String[] args) {
new Demo().hello();
}
}
编译javac -d . Demo.java 生成Demo.class文件和相应目录结构
javah -jni com.jiakai.Demo 生成com_jiakai_Demo.h头文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_jiakai_Demo */
#ifndef _Included_com_jiakai_Demo
#define _Included_com_jiakai_Demo
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_jiakai_Demo
* Method: hello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_jiakai_Demo_hello
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
实现本地方法 com_jiakai_Demo.cpp文件
#include "com_jiakai_Demo.h"
JNIEXPORT void JNICALL Java_com_jiakai_Demo_hello
(JNIEnv * env, jobject obj) {
printf("Hello Jni\n");
return;
};
通过VC编译生成动态库
在此我不得不吐槽下,对于我这个不熟悉VC和动态库的人。遇见了各种各样的由于路径引起Cannot Find的错误。
即使,用了很多网上别人的解决方法也不好使。后来自己用了一个办法解决了。
说说动态库文件的生成。
vc6.0建立一个Win32 Dynamic-Link Libray项目
注意:此处项目名称必须要与上文中load的动态库名一致.
在FileView视图下,把com_jiakai_Demo.h文件导入到Header Files目录下,把com_jiakai_Demo.cpp文件导入到Source Files目录下。
编译运行生成test.dll动态库文件。
在上面生成动态库的过程中,可能会遇到这样的错误 Cannot open include file:jni
我的方法是把jdk include 目录 和 jdk include/win32 目录下所有的.h文件复制到VC98下的iclude目录下。
这样便解决了这个问题。
下一步把test.dll文件放到相应位置就行(classpath能找到就行 这样load的时候才能找到)。
运行java类 java com.jiakai.Demo
结果:
Hello Jni