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. #include <jni.h>
  4. // JNI调用函数必须要用C编译器编译
  5. // C++不加extern "C",调用会有异常
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. /*
  10. * 1、JNIEXPORT、JNICALL:jni的宏
  11. * 2、jstring:返回值类型(对应java的string)
  12. * 3、C方法名:Java_pacakege_class_method
  13. * 4、JNIEnv*、jobject:jni必要参数(jni环境、java对象)
  14. */
  15. JNIEXPORT void JNICALL Java_org_join_jni_JniTest_sayHelloWin (JNIEnv*, jobject, int, int, int, int);
  16. #ifdef __cplusplus
  17. }
  18. #endif
  19. #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;
  10. }
2)CallJava.h
  1. #ifndef CALLJAVA_H_
  2. #define CALLJAVA_H_
  3. #include <jni.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. int add(JNIEnv*, int, int);
  7. int sub(JNIEnv*, int, int);
  8. jobject getInstance(JNIEnv*, jclass);
  9. #endif /* CALLJAVA_H_ */
3)CallJava.cpp
  1. #include "CallJava.h"
  2. /**
  3. * C回调Java方法(静态)
  4. */
  5. int add(JNIEnv *env, int x, int y) {
  6. // 获取类
  7. jclass AnalyzeCidUtil = env->FindClass("org/join/jni/JniTest");
  8. if (NULL == AnalyzeCidUtil) {
  9. return -1;
  10. }
  11. // 获取类add静态方法
  12. /*
  13. * 第三个参数为方法签名
  14. *
  15. * 可用JDK自带工具javap生成该类所有方法签名
  16. * 控制台进入该类class文件目录,输入:javap -s -private 类名
  17. */
  18. jmethodID add = env->GetStaticMethodID(AnalyzeCidUtil, "add", "(II)I");
  19. if (NULL == sub) {
  20. env->DeleteLocalRef(AnalyzeCidUtil); // 删除类指引
  21. return -2;
  22. }
  23. // 调用静态int方法
  24. int result = env->CallStaticIntMethod(AnalyzeCidUtil, add, x, y);
  25. // 返回结果
  26. return result;
  27. }
  28. /**
  29. * C回调Java方法(非静态)
  30. */
  31. int sub(JNIEnv *env, int x, int y) {
  32. // 获取类
  33. jclass AnalyzeCidUtil = env->FindClass("org/join/jni/JniTest");
  34. if (NULL == AnalyzeCidUtil) {
  35. return -1;
  36. }
  37. // 实例化类对象
  38. jobject mAnalyzeCidUtil = getInstance(env, AnalyzeCidUtil);
  39. if (NULL == mAnalyzeCidUtil) {
  40. env->DeleteLocalRef(AnalyzeCidUtil); // 删除类指引
  41. return -2;
  42. }
  43. // 获取对象sub方法
  44. jmethodID sub = env->GetMethodID(AnalyzeCidUtil, "sub", "(II)I");
  45. if (NULL == sub) {
  46. env->DeleteLocalRef(AnalyzeCidUtil); // 删除类指引
  47. env->DeleteLocalRef(mAnalyzeCidUtil); // 删除类对象指引
  48. return -3;
  49. }
  50. // 调用非静态int方法
  51. int result = env->CallIntMethod(mAnalyzeCidUtil, sub, x, y);
  52. // 返回结果
  53. return result;
  54. }
  55. /**
  56. * 实例化类对象
  57. */
  58. jobject getInstance(JNIEnv *env, jclass clazz) {
  59. // 获取构造方法
  60. jmethodID constructor = env->GetMethodID(clazz, "<init>", "()V");
  61. if (NULL == constructor) {
  62. return NULL;
  63. }
  64. // 实例化类对象
  65. return env->NewObject(clazz, constructor);
  66. }
注意静态和非静态方法相差的实例化类对象的区别!
五、后记
附件样例工程有两个,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。

附件:http://down.51cto.com/data/2359729

本文转自winorlose2000 51CTO博客,原文链接:http://blog.51cto.com/vaero/770139,如需转载请自行联系原作者

Java JNI简单实现相关推荐

  1. java jni调用dll文件_Java通过jni调用动态链接库

    (1)JNI简介 JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++).从Java1.1开始,JNI标准成为java ...

  2. Android JNI简单实例(android 调用C/C++代码)

    转载自 xiechengfa 最终编辑 xiechengfa Android JNI简单实例关键字: android.jni Android的jni实例 android 的应用程序(Dalvik VM ...

  3. Java jni 底层_Java中的native是如何实现的(JNI)

    什么是JNI JNI是Java Native Interface的缩写,Java本地接口(JNI)提供了将Java与C/C++.汇编等本地代码集成的方案,该规范使得在 Java 虚拟机内运行的 Jav ...

  4. java jni开发_Java JNI开发实践记录

    当使用到JNI的时候,基本可以肯定Java的平台移植性注定减弱,接下来记录一次使用Java JNI开发的经历. 关于Java JNI的相关资料参见: 下面是使用JNI常见三种场景: 1.在Java应用 ...

  5. Java JNI初体验

    Java JNI初体验 JNI是Java Native Interface的缩写,通过使用 Java本地接口书写程序,可以确保代码在不同的平台上方便移植. 从Java1.1开始,JNI标准成为java ...

  6. java简单通讯录的实现02person类_用java实现简单的小游戏(你一定玩过)

    用java实现简单的小游戏(你一定玩过) 对于java初学者来说,通过一些学习小游戏来对swing学习以及对java基础的学习是一个好的方法,同时也给学习带来了很多的乐趣,接下来就给大家分享一个jav ...

  7. java实现简单窗体小游戏----球球大作战

    java实现简单窗体小游戏----球球大作战 需求分析 1.分析小球的属性: ​ 坐标.大小.颜色.方向.速度 2.抽象类:Ball ​ 设计类:BallMain-创建窗体 ​ BallJPanel- ...

  8. java实现账号单一ip登录,使用Java实现简单后台访问并获取IP示例

    使用Java实现简单后台访问并获取IP示例 发布时间:2020-10-28 21:57:57 来源:亿速云 阅读:92 作者:Leah 使用Java实现简单后台访问并获取IP示例?针对这个问题,这篇文 ...

  9. 用limit 实现java的简单分页

    https://blog.csdn.net/xinyuezitang/article/details/84324359 用limit 实现java的简单分页 xinyuezitang 2018-11- ...

最新文章

  1. ICinsights:中国芯片难达成既定的2025目标
  2. android 封装状态页面,Android 缺省页状态切换方案
  3. Session分布式共享 = Session + Redis + Nginx
  4. 3.7 为什么需要非线性激活函数-深度学习-Stanford吴恩达教授
  5. P7011-[CERC2013]Escape【堆,启发式合并】
  6. java栅格法全局路径规划,基于A*的全局路径规划算法(1)
  7. 安卓应用安全指南 5.6.2 密码学 规则书
  8. Google TakeOut图片下载器
  9. 1000道Python题库系列分享22(40个填空题)
  10. 为了运行内存多两G,多花几百块值不值?
  11. 【基础】算法时空复杂度【OI缩水版】
  12. 大学C语言各章节练习题_及答案合集【350题】《选择题- 判断-程序填空-程序设计》
  13. 统计Java源代码中关键字的数目(每个关键字的数目)
  14. C语言中的斐波那契数列程序
  15. 智鼎逻辑推理题及答案_2019最新玛氏笔试真题节选(含答案及解析)
  16. 影视剪辑,零基础如何自学入门剪辑,视频剪辑入门规划
  17. 替换WIN键和Ctrl键
  18. 超过2t硬盘分区_大于2T的硬盘怎么分区
  19. “瘾品”经济正当道,低度酒成为新财富密码?
  20. 测试进阶篇之测试用例设计-百度云盘

热门文章

  1. VMware虚拟机提示“以独占方式锁定此配置文件失败”解决方案
  2. 【百家稷学】卷积神经网络的前世、今生与未来(武汉工程大学技术分享)
  3. 【AutoML】强化学习如何用于模型蒸馏?
  4. 【NLP】 深度学习NLP开篇-循环神经网络(RNN)
  5. 【mxnet速成】mxnet图像分类从模型自定义到测试
  6. 记一次诡异的SpringMVC中拦截路径的问题
  7. 数据库-数据类型及主键外键
  8. Jquery获取DOM绑定事件
  9. 【GitHub】github相关问题和解决办法
  10. 弱口令的分析和爆破工具使用