[java相关]Java JNI简单实现,
分享于 点击 5863 次 点评:62
[java相关]Java JNI简单实现,
from:http://vaero.blog.51cto.com/4350852/770139
Java JNI简单实现 JNI(Java Native Interface)允许了Java和C&C++进行交互?这不折腾人嘛! 一、JNI简述 http://baike.baidu.com/view/1272329.htm,真心懒了-_-! 二、JNI基本类型 copy表一份,很详细的了!Java类型 | 本地类型 | 描述 |
boolean | jboolean | C/C++8位整型 |
byte | jbyte | C/C++带符号的8位整型 |
char | jchar | C/C++无符号的16位整型 |
short | jshort | C/C++带符号的16位整型 |
int | jint | C/C++带符号的32位整型 |
long | jlong | C/C++带符号的64位整型 |
float | jfloat | C/C++32位浮点型 |
double | jdouble | C/C++64位浮点型 |
Object | jobject | 任何Java对象,或者没有对应java类型的对象 |
Class | jclass | Class对象 |
String | jstring | 字符串对象 |
Object[] | jobjectArray | 任何对象的数组 |
boolean[] | jbooleanArray | 布尔型数组 |
byte[] | jbyteArray | 比特型数组 |
char[] | jcharArray | 字符型数组 |
short[] | jshortArray | 短整型数组 |
int[] | jintArray | 整型数组 |
long[] | jlongArray | 长整型数组 |
float[] | jfloatArray | 浮点型数组 |
double[] | jdoubleArray | 双浮点型数组 |
3)用C&C++方法实现本地方法,编译成动态库 4)Java类中用System.loadLibrary()或System.load()方法加载生成的dll文件 System.loadLibrary():装载Windows\System32下或jre\bin或Tomcat\bin目录下的本地链接库 System.load():根据具体的目录来加截本地链接库,必须是绝对路径 5)OK! 注意jni方法的使用,C&C++格式是不一样的,如下: C 格式:(*env) -> <jni function> (env, <parameters>)
- #ifndef HELLOJNI_H_
- #define HELLOJNI_H_
- #include <jni.h>
- // JNI调用函数必须要用C编译器编译
- // C++不加extern "C",调用会有异常
- #ifdef __cplusplus
- extern "C" {
- #endif
- /*
- * 1、JNIEXPORT、JNICALL:jni的宏
- * 2、jstring:返回值类型(对应java的string)
- * 3、C方法名:Java_pacakege_class_method
- * 4、JNIEnv*、jobject:jni必要参数(jni环境、java对象)
- */
- JNIEXPORT void JNICALL Java_org_join_jni_JniTest_sayHelloWin (JNIEnv*, jobject, int, int, int, int);
- #ifdef __cplusplus
- }
- #endif
- #endif /* HELLOJNI_H_ */
返回jstring:return (*env)->NewStringUTF(env, "XXX");
C++ 格式:env -> <jni function> (<parameters>) 返回jstring:return env->NewStringUTF("XXX"); 另外数组类型的话,jni提供了操作的函数,稍复杂点,例子里没写也就不说了。 四、C&C++回调Java 直接看代码吧,每步都有注释了。 1)包org.join.jni下类JniTest内定义的两方法2)CallJava.h
- /** C回调Java方法(静态) */
- public static int add(int x, int y) {
- System.out.println("==Java静态add方法==");
- return x + y;
- }
- /** C回调Java方法(非静态) */
- public int sub(int x, int y) {
- System.out.println("==Java非静态sub方法==");
- return x - y;
- }
3)CallJava.cpp
- #ifndef CALLJAVA_H_
- #define CALLJAVA_H_
- #include <jni.h>
- #include <stdio.h>
- #include <stdlib.h>
- int add(JNIEnv*, int, int);
- int sub(JNIEnv*, int, int);
- jobject getInstance(JNIEnv*, jclass);
- #endif /* CALLJAVA_H_ */
注意静态和非静态方法相差的实例化类对象的区别! 五、后记 附件样例工程有两个,JavaJni是Java工程,JniDll_win32是VS2010工程。 Java工程带了在我环境下编译的dll,可直接跑,但我相信大多数人都跑不通-_-!(在朋友电脑上曾试过,可能是Java不同版本的原因吧)
- #include "CallJava.h"
- /**
- * C回调Java方法(静态)
- */
- int add(JNIEnv *env, int x, int y) {
- // 获取类
- jclass AnalyzeCidUtil = env->FindClass("org/join/jni/JniTest");
- if (NULL == AnalyzeCidUtil) {
- return -1;
- }
- // 获取类add静态方法
- /*
- * 第三个参数为方法签名
- *
- * 可用JDK自带工具javap生成该类所有方法签名
- * 控制台进入该类class文件目录,输入:javap -s -private 类名
- */
- jmethodID add = env->GetStaticMethodID(AnalyzeCidUtil, "add", "(II)I");
- if (NULL == sub) {
- env->DeleteLocalRef(AnalyzeCidUtil); // 删除类指引
- return -2;
- }
- // 调用静态int方法
- int result = env->CallStaticIntMethod(AnalyzeCidUtil, add, x, y);
- // 返回结果
- return result;
- }
- /**
- * C回调Java方法(非静态)
- */
- int sub(JNIEnv *env, int x, int y) {
- // 获取类
- jclass AnalyzeCidUtil = env->FindClass("org/join/jni/JniTest");
- if (NULL == AnalyzeCidUtil) {
- return -1;
- }
- // 实例化类对象
- jobject mAnalyzeCidUtil = getInstance(env, AnalyzeCidUtil);
- if (NULL == mAnalyzeCidUtil) {
- env->DeleteLocalRef(AnalyzeCidUtil); // 删除类指引
- return -2;
- }
- // 获取对象sub方法
- jmethodID sub = env->GetMethodID(AnalyzeCidUtil, "sub", "(II)I");
- if (NULL == sub) {
- env->DeleteLocalRef(AnalyzeCidUtil); // 删除类指引
- env->DeleteLocalRef(mAnalyzeCidUtil); // 删除类对象指引
- return -3;
- }
- // 调用非静态int方法
- int result = env->CallIntMethod(mAnalyzeCidUtil, sub, x, y);
- // 返回结果
- return result;
- }
- /**
- * 实例化类对象
- */
- jobject getInstance(JNIEnv *env, jclass clazz) {
- // 获取构造方法
- jmethodID constructor = env->GetMethodID(clazz, "<init>", "()V");
- if (NULL == constructor) {
- return NULL;
- }
- // 实例化类对象
- return env->NewObject(clazz, constructor);
- }
总之不行或者非win32系统的话重新编译吧,源文件在JniDll_win32工程内都有。注意include Java安装目录下include文件夹内的头文件哦。VS2010的话,右键工程 -> Properties -> Configuration Properties -> C/C++ -> General -> Additional Include Directories内设置,如:%JAVA_HOME%\include;%JAVA_HOME%\include\win32。
相关文章
- 暂无相关文章
用户点评