Java很好地封装了硬件,最大可能地规避了不同硬件平台的硬件处理,让程序员能专注于软件。但是“寄人篱下哪能不弯腰”?当然这么说有一些情绪化,Java与C/C++相比有一个无法避开的劣势——效率!C算是离硬件最近的高级语言,特别是在嵌入式应用领域,C可以直接操作内存,直面硬件而执行。对于小型移动设备而言具有无法拒绝的优跃性。
于是常在岸上走的Java,在这种情况下不得不下水。JNI便出现了,它在Java与C/C++之间提供了一个本地库的调用接口,使得Java与不同语言间可以相互沟通协作。
工作准备:
1、Linux:本文测试环境为Ubuntu12.04LTS,其他Ubuntu版本或Linux应该也能实现。当然,Windows与Mac也是可以的,只是操作上略有不同。
2、JDK1.8_131:用于编译执行Java程序,其他版本的JDK也可以。
3、gcc:用于将C或C++程序编译成动态或静态库。
本文默认已准备好环境。
一、编写Java程序,MyJni.java
public class MyJni {
static{
System.load("/home/smallfish/workspace/Java/libmyjni.so");
}
public native void display();
public native double sum(double x, double y);
public static void main(String[] args) {
MyJni myJni = new MyJni();
System.out.print(myJni.sum(1,1));
System.out.print("\n");
myJni.display();
}
}
- public class MyJni {
- static{
- System.load("/home/smallfish/workspace/Java/libmyjni.so");
- }
- public native void display();
- public native double sum(double x, double y);
- public static void main(String[] args) {
- MyJni myJni = new MyJni();
- System.out.print(myJni.sum(1,1));
- System.out.print("\n");
- myJni.display();
- }
- }
public class MyJni {
static{
System.load("/home/smallfish/workspace/Java/libmyjni.so");
}
public native void display();
public native double sum(double x, double y);
public static void main(String[] args) {
MyJni myJni = new MyJni();
System.out.print(myJni.sum(1,1));
System.out.print("\n");
myJni.display();
}
}
1、在Java类中只需要声明native方法 ,这两个方法的实现是在libmyjni.so中,所以需要加载此库,使用System.load("库文件的绝对路径")。
2、使用javah生成本地方法头文件,MyJni.h
# javah MyJni
- # javah MyJni
# javah MyJni
javah会自动生成MyJni.h文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class MyJni */
#ifndef _Included_MyJni
#define _Included_MyJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: MyJni
* Method: display
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_MyJni_display
(JNIEnv *, jobject);
/*
* Class: MyJni
* Method: sum
* Signature: (DD)D
*/
JNIEXPORT jdouble JNICALL Java_MyJni_sum
(JNIEnv *, jobject, jdouble, jdouble);
#ifdef __cplusplus
}
#endif
#endif
- /* DO NOT EDIT THIS FILE - it is machine generated */
- #include <jni.h>
- /* Header for class MyJni */
- #ifndef _Included_MyJni
- #define _Included_MyJni
- #ifdef __cplusplus
- extern "C" {
- #endif
- /*
- * Class: MyJni
- * Method: display
- * Signature: ()V
- */
- JNIEXPORT void JNICALL Java_MyJni_display
- (JNIEnv *, jobject);
- /*
- * Class: MyJni
- * Method: sum
- * Signature: (DD)D
- */
- JNIEXPORT jdouble JNICALL Java_MyJni_sum
- (JNIEnv *, jobject, jdouble, jdouble);
- #ifdef __cplusplus
- }
- #endif
- #endif
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class MyJni */
#ifndef _Included_MyJni
#define _Included_MyJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: MyJni
* Method: display
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_MyJni_display
(JNIEnv *, jobject);
/*
* Class: MyJni
* Method: sum
* Signature: (DD)D
*/
JNIEXPORT jdouble JNICALL Java_MyJni_sum
(JNIEnv *, jobject, jdouble, jdouble);
#ifdef __cplusplus
}
#endif
#endif
二、用C语言实现native方法MyJni.c
#include "jni.h"
#include "MyJni.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_MyJni_display(JNIEnv *env, jobject obj){
env = env;
obj = obj;
printf("Hello, JNI!\n");
}
JNIEXPORT jdouble JNICALL Java_MyJni_sum(JNIEnv *env, jobject obj, jdouble a, jdouble b){
env = env;
obj = obj;
return a+b;
}
- #include "jni.h"
- #include "MyJni.h"
- #include <stdio.h>
- JNIEXPORT void JNICALL Java_MyJni_display(JNIEnv *env, jobject obj){
- env = env;
- obj = obj;
- printf("Hello, JNI!\n");
- }
- JNIEXPORT jdouble JNICALL Java_MyJni_sum(JNIEnv *env, jobject obj, jdouble a, jdouble b){
- env = env;
- obj = obj;
- return a+b;
- }
#include "jni.h"
#include "MyJni.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_MyJni_display(JNIEnv *env, jobject obj){
env = env;
obj = obj;
printf("Hello, JNI!\n");
}
JNIEXPORT jdouble JNICALL Java_MyJni_sum(JNIEnv *env, jobject obj, jdouble a, jdouble b){
env = env;
obj = obj;
return a+b;
}
注意:
1、jni.h是Java提供的头文件,它在JDK的"安装目录/include"目录下
2、jni_md.h在JDK“安装目录/include/linux”目录下。
为了编译方便于是乎将这两个文件与MyJni.c文件放在一起,所以使用“#include "jni.h" ”。
三、将C实现编译成动态链接库
# gcc -fPIC -c MyJni.c
# gcc -fPIC -shared MyJni.o -o libmyjni.so
- # gcc -fPIC -c MyJni.c
- # gcc -fPIC -shared MyJni.o -o libmyjni.so
# gcc -fPIC -c MyJni.c
# gcc -fPIC -shared MyJni.o -o libmyjni.so
生成库文件后将此文件放至Java程序加载库的路径下。
四、编译Java文件
#javac MyJni.java
- #javac MyJni.java
#javac MyJni.java
五、执行
转载请注明:OpenMind » Java JNI初体验