大家都知道一般情况下C语言的执行效率要高于java语言,优化的C代码执行效率接近汇编
而且在项目开发中,一般使用java语言做界面,核心业务逻辑,与服务器交互都可以用C和C++来编写
这样以来就出现了jni,使用JAVA调用C,C回调JAVA
其实JNI就是C接口和JAVA接口的一种映射,java类里面声明native函数,将java带有native函数的类编译成头文件,由C和C++来编写实现文件,最后将其打包成dll文件,放在java的bin目录下,最后执行java文件即可。
废话少说:
看代码:
package cn.edu.wtu;
public class Caculator{
static {
System.loadLibrary("caculator");
}
public native int add(int a,int b);
public native int multiplication(int a,int b);
public native int subtraction(int a,int b);
public native int division(int a,int b);
public static void main(String []args){
Caculator caculator=new Caculator();
System.out.println("加法:add(8,4):"+caculator.add(8,4));
System.out.println("乘法: multiplication(8,4):"+caculator.multiplication(8,4));
System.out.println("减法:subtraction(8,4):"+caculator.subtraction(8,4));
System.out.println("除法:division(8,4):"+caculator.division(8,4));
}
}
编译:
javac -d . Caculator
注意:javac 和-d这个参数有空格,还有“.”和Caculator和-d参数之间也有空格
然后再生成头文件:
javah cn.edu.wtu.Caculator
使用vs2005新建一个C++项目,注意是win32 project
然后选择dll项目
将你生成的头文件copy到vs2005的项目中
头文件代码:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class cn_edu_wtu_Caculator */
#ifndef _Included_cn_edu_wtu_Caculator
#define _Included_cn_edu_wtu_Caculator
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: cn_edu_wtu_Caculator
* Method: add
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_cn_edu_wtu_Caculator_add
(JNIEnv *, jobject, jint, jint);
/*
* Class: cn_edu_wtu_Caculator
* Method: multiplication
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_cn_edu_wtu_Caculator_multiplication
(JNIEnv *, jobject, jint, jint);
/*
* Class: cn_edu_wtu_Caculator
* Method: subtraction
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_cn_edu_wtu_Caculator_subtraction
(JNIEnv *, jobject, jint, jint);
/*
* Class: cn_edu_wtu_Caculator
* Method: division
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_cn_edu_wtu_Caculator_division
(JNIEnv *, jobject, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
代码如下:
// test_caculator.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "cn_edu_wtu_Caculator.h"
#include <stdio.h>
#include <jni.h>
JNIEXPORT jint JNICALL Java_cn_edu_wtu_Caculator_add
(JNIEnv *, jobject, jint a, jint b){
return a+b;
}
/*
* Class: cn_edu_wtu_Caculator
* Method: multiplication
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_cn_edu_wtu_Caculator_multiplication
(JNIEnv *, jobject, jint a, jint b){
return a*b;
}
/*
* Class: cn_edu_wtu_Caculator
* Method: subtraction
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_cn_edu_wtu_Caculator_subtraction
(JNIEnv *, jobject, jint a , jint b){
return a-b;
}
/*
* Class: cn_edu_wtu_Caculator
* Method: division
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_cn_edu_wtu_Caculator_division
(JNIEnv *, jobject, jint a, jint b){
return a/b;
}
注意要生成javac能调用的dll还有连个头文件:
一个是java的jdk目录下的include目录下的jni。h文件
还有一个是jdk目录下的include目录下的win32目录下的jni_md。h文件
一般只要在cpp代码文件中写下include jni。就够了,
因为jni头文件里面已经包含了jni_md。h文件了
在vs2005中点击toos菜单项,options子项,然后选择projections and solutions项的VC++Directories
platform: win32
show directories for:include files
连续添加两项:
C:/Java/jdk1.6.0_19/include
C:/Java/jdk1.6.0_19/include/win32
注意这是我的jdk目录,各有有所不同。
最后在vs2005中build,然后在debug目录下找到对应的dll文件
将其copy到jdk的bin目录下,注意名字要和System.loadLibrary("caculator");中的String相同,这里不必加上扩展名
依赖具体的OS帮你加上,Linux下是lib+名字,也不要扩展名,当然Linux下是。so文件
最后执行java文件:
D:/jni>java cn.edu.wtu.Caculator
加法:add(8,4):12
乘法: multiplication(8,4):32
减法:subtraction(8,4):4
除法:division(8,4):2