[java相关]Java JNI简单实现

来源:互联网 发布:麦当劳四川辣酱 知乎 编辑:程序博客网 时间:2024/06/05 11:30

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
双浮点型数组
表2 Java类型映射
 
三、Java调用C&C++
         1)Java类中编写native声明的方法。
         2)javah命令生成JNI样式.h文件。
         貌似我一直是直接建一个.h,然后copy之前的改改完事。需要注意以下几点:1、JNI调用函数必须要用C编译器编译。也就是C++别忘了extern "C"那块;2、方法名格式:Java_pacakege_class_method。
 
例子程序的HelloJni.h文件:
 
  1. #ifndef HELLOJNI_H_ 
  2. #define HELLOJNI_H_ 
  3.  
  4. #include <jni.h> 
  5.  
  6. // JNI调用函数必须要用C编译器编译 
  7. // C++不加extern "C",调用会有异常 
  8. #ifdef __cplusplus 
  9. extern "C" { 
  10. #endif 
  11.  
  12. /* 
  13.  * 1、JNIEXPORT、JNICALL:jni的宏 
  14.  * 2、jstring:返回值类型(对应java的string) 
  15.  * 3、C方法名:Java_pacakege_class_method 
  16.  * 4、JNIEnv*、jobject:jni必要参数(jni环境、java对象) 
  17.  */ 
  18. JNIEXPORT void JNICALL Java_org_join_jni_JniTest_sayHelloWin (JNIEnv*, jobject, intintintint); 
  19.  
  20. #ifdef __cplusplus 
  21. #endif 
  22.  
  23. #endif /* HELLOJNI_H_ */ 
 
         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>)

                  返回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内定义的两方法
  1. /** C回调Java方法(静态) */ 
  2. public static int add(int x, int y) { 
  3. System.out.println("==Java静态add方法=="); 
  4. return x + y; 
  5.  
  6. /** C回调Java方法(非静态) */ 
  7. public int sub(int x, int y) { 
  8. System.out.println("==Java非静态sub方法=="); 
  9. return x - y; 
 
2)CallJava.h
  1. #ifndef CALLJAVA_H_ 
  2. #define CALLJAVA_H_ 
  3.  
  4. #include <jni.h> 
  5. #include <stdio.h> 
  6. #include <stdlib.h> 
  7.  
  8. int add(JNIEnv*, intint); 
  9. int sub(JNIEnv*, intint); 
  10.  
  11. jobject getInstance(JNIEnv*, jclass); 
  12.  
  13. #endif /* CALLJAVA_H_ */ 
 
3)CallJava.cpp
  1. #include "CallJava.h" 
  2.  
  3. /** 
  4.  * C回调Java方法(静态) 
  5.  */ 
  6. int add(JNIEnv *env, int x, int y) { 
  7.     // 获取类 
  8.     jclass AnalyzeCidUtil = env->FindClass("org/join/jni/JniTest"); 
  9.     if (NULL == AnalyzeCidUtil) { 
  10.         return -1; 
  11.     } 
  12.  
  13.     // 获取类add静态方法 
  14.     /* 
  15.      * 第三个参数为方法签名 
  16.      * 
  17.      * 可用JDK自带工具javap生成该类所有方法签名 
  18.      * 控制台进入该类class文件目录,输入:javap -s -private 类名 
  19.      */ 
  20.     jmethodID add = env->GetStaticMethodID(AnalyzeCidUtil, "add""(II)I"); 
  21.     if (NULL == sub) { 
  22.         env->DeleteLocalRef(AnalyzeCidUtil); // 删除类指引 
  23.         return -2; 
  24.     } 
  25.  
  26.     // 调用静态int方法 
  27.     int result = env->CallStaticIntMethod(AnalyzeCidUtil, add, x, y); 
  28.  
  29.     // 返回结果 
  30.     return result; 
  31.  
  32. /** 
  33.  * C回调Java方法(非静态) 
  34.  */ 
  35. int sub(JNIEnv *env, int x, int y) { 
  36.     // 获取类 
  37.     jclass AnalyzeCidUtil = env->FindClass("org/join/jni/JniTest"); 
  38.     if (NULL == AnalyzeCidUtil) { 
  39.         return -1; 
  40.     } 
  41.  
  42.     // 实例化类对象 
  43.     jobject mAnalyzeCidUtil = getInstance(env, AnalyzeCidUtil); 
  44.     if (NULL == mAnalyzeCidUtil) { 
  45.         env->DeleteLocalRef(AnalyzeCidUtil); // 删除类指引 
  46.         return -2; 
  47.     } 
  48.  
  49.     // 获取对象sub方法 
  50.     jmethodID sub = env->GetMethodID(AnalyzeCidUtil, "sub""(II)I"); 
  51.     if (NULL == sub) { 
  52.         env->DeleteLocalRef(AnalyzeCidUtil); // 删除类指引 
  53.         env->DeleteLocalRef(mAnalyzeCidUtil); // 删除类对象指引 
  54.         return -3; 
  55.     } 
  56.  
  57.     // 调用非静态int方法 
  58.     int result = env->CallIntMethod(mAnalyzeCidUtil, sub, x, y); 
  59.  
  60.     // 返回结果 
  61.     return result; 
  62.  
  63. /** 
  64.  * 实例化类对象 
  65.  */ 
  66. jobject getInstance(JNIEnv *env, jclass clazz) { 
  67.     // 获取构造方法 
  68.     jmethodID constructor = env->GetMethodID(clazz, "<init>""()V"); 
  69.     if (NULL == constructor) { 
  70.         return NULL; 
  71.     } 
  72.     // 实例化类对象 
  73.     return env->NewObject(clazz, constructor); 
 
         注意静态和非静态方法相差的实例化类对象的区别!
 
五、后记
         附件样例工程有两个,JavaJni是Java工程,JniDll_win32是VS2010工程。
         Java工程带了在我环境下编译的dll,可直接跑,但我相信大多数人都跑不通-_-!(在朋友电脑上曾试过,可能是Java不同版本的原因吧)

         总之不行或者非win32系统的话重新编译吧,源文件在JniDll_win32工程内都有。注意include Java安装目录下include文件夹内的头文件哦。VS2010的话,右键工程 -> Properties -> Configuration Properties -> C/C++ -> General -> Additional Include Directories内设置,如:%JAVA_HOME%\include;%JAVA_HOME%\include\win32。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 法院判决书下来了钱还保全么怎么办 深圳路边泊车不知道泊车编号怎么办 当事人进拘留所了我的工资怎么办 昆明公租房住满5年后怎么办 昆明公租房房子到期缴纳金怎么办 看守所犯人银行卡里钱没用完怎么办 中国邮政迟迟没有把信件寄到怎么办 拘留15天放出来还不肯还钱怎么办 人死在拘留所不让看监控怎么办 家人吸毒可他又不愿强戒怎么办 容留他人吸毒时签了强戒怎么办 拘留后发现被拘留是人大代表怎么办 执行局要拘留人找不到人怎么办 开设赌场罪拘留37天了该怎么办 对治安处罚光罚款不拘留怎么办 打架和解后警察不给消案怎么办 12个人片诈骗刑拘了28天怎么办 交警拘留几天后还是没钱赔偿怎么办 平安车主信用卡车牌号填错了怎么办 起诉借钱的人逮起来了怎么办 在法院查不到坐牢人的档案怎么办 人被冤枉敲诈勒索进看守所了怎么办 打架被拘留孩子怎么办三周了 技师被拘留她的家人该怎么办 我是担保人贷款人跑了我该怎么办 公司依旷工理由辞退我该怎么办 试工两天被辞退了不发工资怎么办 员工在单位被打监控调不出来怎么办 老师罚做60张试卷家长该怎么办 孩子在幼儿园被老师打该怎么办 孩子被孩子打了老师该怎么办? 法院判决书下来后看守所不收怎么办 因病看守所不收押发院判了怎么办 现在显示还在看守所羁押需要怎么办 嫖了N多年丈夫让我怎么办 预约考试的登录密码忘了怎么办 人进了看守所信用卡没还怎么办 上海租房人放2个麻将台怎么办 南宁公租房住满5年后怎么办 合伙买房时如果出售意见不合怎么办 老旧小区改造下水一楼不同意怎么办