一、JNI提供了一系列的接口,允许java类与使用C/C++等其他编程语言编写的应用程序、模块、库进行交互操作。比如,在java类中使用C语言库中的特定函数,或者在C语言程序中使用java类库,都需要借助JNI来完成。通常在下列几种情况下使用JNI:
1)注重处理速度:与本地代码(c/c++)相比,java代码的执行速度要相对慢一些,如果对某段程序的执行速度有较高的要求,建议使用c/c++编写代码。而后在java中通过jni调用,常常能够获得更快的运行速度。
2)硬件控制:为了更好地控制硬件,硬件控制代码通常使用C语言编写,然后借助JNI将其与java层连接起来,从而实现对硬件的控制。
3)既有C/C++代码的复用:使用一些已经编写好了的C/C++代码,就要通过JNI来调用。
二、在java代码中通过JNI调用C函数的步骤如下:
1)编写java代码
public class HelloJni {
native void printHello(); //nativa告知java编译器,在java代码中带有该关键字的方法只是声明,具体由其它语言编写实现。
native void printString(String str);
static{
System.loadLibrary("hellojni"); //windows下hellojni.dll将会被加载,Linux下libhellojni.so将会被加载。
}
public static void main(String[] args) {
HelloJni h=new HelloJni();
h.printHello();
h.printString("hello world for my first jni");
}
}
2)编译java代码,生成.class文件:javac HelloJni.java
3)生成C语言头文件:运行javah HelloJni会生成HelloJni.h文件如下
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloJni */
#ifndef _Included_HelloJni
#define _Included_HelloJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloJni
* Method: printHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloJni_printHello
(JNIEnv *, jobject);
/*
* Class: HelloJni
* Method: printString
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_HelloJni_printString
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
4)编写C代码
#include "HelloJni.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_HelloJni_printHello
(JNIEnv *env, jobject obj)
{
printlf("hello world");
return;
}
JNIEXPORT void JNICALL Java_HelloJni_printString
(JNIEnv *env, jobject obj, jstring string)
{
const char *str=(*env)->GetStringUTFChars(env,string,0);
printf("%s!/n",str);
return;
}
5)生成C共享库,生成hellojni.dll
6)运行java代码,运行HelloJNI类,并查看输出结果是否正常。