JNI编程(二) —— 让C++和Java相互调用(2)
3.getRamdomOrder()
这个方法会从backend得到一个随机的Order对象(抱歉这里“Random”拼错了),然后再调用java中相应的通知方法来通知foreground。getRamdomOrder方法没有参数,但是所对应的C++方法里却有两个参数,一定有人会不解。其实细心的朋友一定会发现,JNI里所有对应Java方法的C++ 方法都会比Java方法多两个参数,第一个参数是我们很熟悉的JNIEnv*指针,第二个参数有时是jobject有时是个jclass。针对这第二个参数在这里有必要多废话两句。
其实第二个参数传递的是包含了native本地方法的对象或者类对象,我们知道非静态的方法是属于某一个对象的,而静态方法是属于类对象的,所以静态方法可以被所有对象共享。有这个对象/类对象,我们就可以很方便的操作包含了native方法的对象的一些函数了。(这句话有点绕口,没看明白的建议多读两遍)。
废话完了言归正传,因为getRamdomOrder不是静态的,所以C++相对应的参数中传递来的是一个jobject对象。
- jclass business_class = env->GetObjectClass(obj);
这一句不难理解,GetObjectClass方法可以得到一个对象的类对象,这句有点像Java中的Object.class。不熟悉的朋友建议再去看一下Java反射机制。接下来的几句C++代码应该在之前的方法1和方法2中都解释过。早backend端会发一个“消息”给foreground,之后new一个新的Order类出来。接下来的三句有必要再废话一下。
- jfieldID amount_field = env->GetFieldID(order_class, "amount", "I");
- jint amount = env->GetIntField(order, amount_field);
- cout << "amount: " << amount << endl;
之前我为Order这个Javabean的amount的属性设置了一个初始值为30,其实就是为了在这里演示如何在C++中拿一个Java对象的属性,拿的方法和我们之前说过的调用Java方法的程序差不多,也要先拿到一个jfieldID,之后调用Get<type>Field方法来取得某一个对象中的某一个属性的数值,最后cout把他打印出来。我们编写测试代码来看一下最终效果。
- Business b = new Business();
- Order o2 = b.getRamdomOrder();
- System.out.println(o2.getName());
运行上述的测试代码之后,控制台上打出了
Got a notification.
amount: 30
Fruit
和我们想要的结果是一样的,测试成功。
4.analyzeOrder(Order order)
这是一个静态方法,foreground会通过这个方法传一个Order的对象到backend去,然后再由CPP端进行“analyze”。在这里我们取出来传递过来的Order对象的name属性,然后打印到控制台上。因为这个方法是静态static方法,所以相对应的C++方法中的第二个参数也变成了jclass对象,也就是Business.class这个类对象。第三个参数是一个jobject对象,很明显就是我们传递过来的order对象。
前5句代码应该不难理解,就是调用getName这个方法,然后打印出来。因为JNI的API中并没有提供CallStringMethod这个方法,所以我们用CallObjectMethod这个方法来取得name这个字符串(String很明显也是一个Object),然后再转型成为jstring。也就是下面这句代码。
- jstring name_str = static_cast<jstring>(env->CallObjectMethod(obj, getName_method));
取到了name这个字符串之后cout打印出来,之后调用Business这个类对象中的静态方法notificationByStatic来通知foreground。调用的流程以及方法和非静态都是一样的,只不过注意JNI中调用静态方法的API所传递的一个参数是一个jclass而非jobject(这个也不难理解,因为静态方法是属于class类对象的)
还是编写测试代码测试这个方法
- Business b = new Business();
- Order o = b.getOrder("Watermelom", 100);
- Business.analyzeOrder(o);
控制台上打印出
Name in Java_com_chnic_service_Business_analyzeOrder: Watermelom
Got a notification in a static method.
第一句是C++中cout打印出来的,第二句则是Java中的静态方法打印出来的,和我们想要的结果是一致的。
呼~好不容易介绍完了4个方法,最后总结一下吧。
- JNI中所提供的API远远不止这4个方法中所使用的API。上面介绍的都是比较常用的,本人也不可能罗列出所有的API。
- 了解了JNI编程更加有利于深入了解Java中的反射机制,反之亦然。
因此如果有对JNI编程有兴趣或者有更深入的需要,可以参考一下sun的相关文档。在这里上传sun提供的JNI的API手册,还有上面例子中所用的演示代码给大家参考。
JNI编程(二) —— 让C++和Java相互调用(2)的更多相关文章
- JNI编程(二) —— 让C++和Java相互调用(1)
自己在外面偷偷的算了下,又有将近两个月没更新过blog了.趁着今天有兴致,来更新JNI编程的第二篇文章.在第一篇里,大概介绍了JNI的特点.用途和优劣.并且做一个最简单的JNI的例子,不过说实话那个例 ...
- R语言- 实验报告 - 利用R语言脚本与Java相互调用
一. 实训内容 利用R语言对Java项目程序进行调用,本实验包括利用R语言对java的.java文件进行编译和执行输出. 在Java中调用R语言程序.本实验通过eclipse编写Java程序的方式,调 ...
- Cocos2d-x通过Jni实现C++与Java相互调用
在cocos2dx项目中与运营平台(java sdk)对接时使用了JNI. 通过C++调用Java 在JniUtil.h文件中如下实现: #ifndef _JNIUTIL_H_ #define _JN ...
- 苹果系统开发中的混合编程(2):Swift和C的相互调用
在进行Swift和C之间的相互调用时,有必要先了解一下两种语言之间的类型转换关系: C 类型 Swift 类型 bool CBool char, signed char CChar unsig ...
- 苹果系统开发中的混合编程(1):Objective-C和C++的相互调用
首先是OC调用C++的代码. 创建一个Objective-C的项目,并创建c++文件MyCppFile.hpp和MyCppFile.cpp. 把要调用Cpp代码的文件名改成mm后缀名,项目代码 ...
- 解析Java的JNI编程中的对象引用与内存泄漏问题
JNI,Java Native Interface,是 native code 的编程接口.JNI 使 Java 代码程序可以与 native code 交互——在 Java 程序中调用 native ...
- 在 JNI 编程中避免内存泄漏
JAVA 中的内存泄漏 JAVA 编程中的内存泄漏,从泄漏的内存位置角度可以分为两种:JVM 中 Java Heap 的内存泄漏:JVM 内存中 native memory 的内存泄漏. Java H ...
- .Net 与 Java 的服务接口相互调用
本文介绍.Net 与 Java 相互调用的例子.下面的介绍主要包括三方面:一是通过常用Web服务进行相互调用,二是使用TCP/IP套接字进行相互调用,三是使用Remote实现远程对象相互调用. 首先说 ...
- 在 JNI 编程中避免内存泄漏与崩溃
JNI 编程简介 JNI,Java Native Interface,是 native code 的编程接口.JNI 使 Java 代码程序可以与 native code 交互——在 Java 程序中 ...
随机推荐
- python内置函数大全
一.数学运算类 abs(x) 求绝对值1.参数可以是整型,也可以是复数2.若参数是复数,则返回复数的模 complex([real[, imag]]) 创建一个复数 divmod(a, b) 分别取商 ...
- 清橙 A1120 拦截导弹 -- 动态规划(最长上升子序列)
题目地址:http://oj.tsinsen.com/A1120 问题描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但 ...
- HTML5之Canvas画布
先上代码: <canvas width="1000" height="800">浏览器不支持HTML5!</canvas> <sc ...
- AJAX安全-Session做Token
个人思路,请大神看到了指点 个人理解token是防止扫号机或者恶意注册.恶意发表灌水,有些JS写的token算法,也会被抓出来被利用,个人感觉还是用会过期的Session做token更好,服务器存储, ...
- win7 蛋疼的时间格式转化
win7系统 获得系统时间为 2015年1月1日 星期5 10:10 数据库中时间格式 是不认识的 转化为 DateTime.Now.ToString("yyyy-MM-dd HH:mm:s ...
- IOS中如何自定义web应用的图标
在iPhone/iPad等苹果移动设备上,可以把网站”添加至主屏幕”,添加时的图标可以在HTML中自定义设置图片. 可以使用apple-touch-icon和apple-touch-icon-prec ...
- 007.Compiled
Delphi property Compiled: Boolean read FCompiled; 类型:property 可见性:public 所在单元:System.RegularExpressi ...
- RSA使用 常识
1公钥加密,私钥解密 OK反过来, 私钥加密,公钥解密 也OK 2 使用RSA加密 对称算法的key ,用对称算法加密 消息.伙伴收到消息后,RSA解密出 对称算法的key,再用这个key去解密消息 ...
- DBMS_SCHEDULER and DBMS_JOB
引用原文:http://foolraty.iteye.com/blog/1107803 For DBMS_JOB usage:To find out more information about th ...
- csv转json文件
今天因为需要帮一个同事的新闻内容录入为html, 每次手改不方便,所以就弄了个csv(excel)转json的c++程序,然后再利用ejs把它渲染成网页,打开渲染好的网页再保存(不能保存源文件,不然还 ...