当前位置: 首页 > news >正文

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对象。

 

Cpp代码   收藏代码
  1. jclass business_class = env->GetObjectClass(obj);  

 

这一句不难理解,GetObjectClass方法可以得到一个对象的类对象,这句有点像Java中的Object.class。不熟悉的朋友建议再去看一下Java反射机制。接下来的几句C++代码应该在之前的方法1和方法2中都解释过。早backend端会发一个“消息”给foreground,之后new一个新的Order类出来。接下来的三句有必要再废话一下。

 

Cpp代码   收藏代码
  1. jfieldID amount_field = env->GetFieldID(order_class, "amount", "I");  
  2. jint amount = env->GetIntField(order, amount_field);  
  3. cout << "amount: " << amount << endl;  

 

之前我为Order这个Javabean的amount的属性设置了一个初始值为30,其实就是为了在这里演示如何在C++中拿一个Java对象的属性,拿的方法和我们之前说过的调用Java方法的程序差不多,也要先拿到一个jfieldID,之后调用Get<type>Field方法来取得某一个对象中的某一个属性的数值,最后cout把他打印出来。我们编写测试代码来看一下最终效果。

 

Java代码   收藏代码
  1. Business b = new Business();                   
  2. Order o2 = b.getRamdomOrder();  
  3. 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。也就是下面这句代码。

 

Cpp代码   收藏代码
  1. jstring name_str = static_cast<jstring>(env->CallObjectMethod(obj, getName_method));  

 

取到了name这个字符串之后cout打印出来,之后调用Business这个类对象中的静态方法notificationByStatic来通知foreground。调用的流程以及方法和非静态都是一样的,只不过注意JNI中调用静态方法的API所传递的一个参数是一个jclass而非jobject(这个也不难理解,因为静态方法是属于class类对象的)

 

还是编写测试代码测试这个方法

 

Java代码   收藏代码
  1. Business b = new Business();          
  2. Order o = b.getOrder("Watermelom", 100);  
  3. Business.analyzeOrder(o);  

 

控制台上打印出

 

Name in Java_com_chnic_service_Business_analyzeOrder: Watermelom
Got a notification in a static method.

 

第一句是C++中cout打印出来的,第二句则是Java中的静态方法打印出来的,和我们想要的结果是一致的。

 

 

呼~好不容易介绍完了4个方法,最后总结一下吧。

 

  1. JNI中所提供的API远远不止这4个方法中所使用的API。上面介绍的都是比较常用的,本人也不可能罗列出所有的API。
  2. 了解了JNI编程更加有利于深入了解Java中的反射机制,反之亦然。

 

因此如果有对JNI编程有兴趣或者有更深入的需要,可以参考一下sun的相关文档。在这里上传sun提供的JNI的API手册,还有上面例子中所用的演示代码给大家参考。

转载于:https://www.cnblogs.com/Ph-one/p/4690718.html

相关文章:

  • char*,const char*和string的相互转换
  • 请问什么是UTF字符串?
  • jni数据问题
  • sprintf
  • 锦上
  • eMMC(KLM8G2FE3B)
  • jni调试3(线程调试env变量问题)
  • 在JNI中新开线程遇到问题
  • 当函数没有return时错误
  • 三星 PMU NXE2000,x-powers的AXP228,NXE2000
  • android-86-Can't create handler inside thread that has not called Looper.prepare()
  • LM393,LM741可以用作电压跟随器吗?
  • android原生系统裁剪
  • 在ubuntu12.04下编译android4.1.2添加JNI层出现问题
  • android学习计划2
  • 网络传输文件的问题
  • 【刷算法】求1+2+3+...+n
  • eclipse的离线汉化
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • node-sass 安装卡在 node scripts/install.js 解决办法
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 后端_MYSQL
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 力扣(LeetCode)357
  • 嵌入式文件系统
  • 区块链将重新定义世界
  • 设计模式(12)迭代器模式(讲解+应用)
  • 消息队列系列二(IOT中消息队列的应用)
  • 以太坊客户端Geth命令参数详解
  • 你对linux中grep命令知道多少?
  • 7行Python代码的人脸识别
  • 交换综合实验一
  • 小白应该如何快速入门阿里云服务器,新手使用ECS的方法 ...
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • (3)(3.5) 遥测无线电区域条例
  • (echarts)echarts使用时重新加载数据之前的数据存留在图上的问题
  • (Matlab)使用竞争神经网络实现数据聚类
  • (Oracle)SQL优化技巧(一):分页查询
  • (pojstep1.1.1)poj 1298(直叙式模拟)
  • (附源码)springboot助农电商系统 毕业设计 081919
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (十二)python网络爬虫(理论+实战)——实战:使用BeautfulSoup解析baidu热搜新闻数据
  • (四)Controller接口控制器详解(三)
  • .Family_物联网
  • .jks文件(JAVA KeyStore)
  • .NET Core中Emit的使用
  • .net refrector
  • .net 提取注释生成API文档 帮助文档
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • .NET导入Excel数据
  • .net使用excel的cells对象没有value方法——学习.net的Excel工作表问题
  • .vimrc php,修改home目录下的.vimrc文件,vim配置php高亮显示
  • @四年级家长,这条香港优才计划+华侨生联考捷径,一定要看!
  • [20160807][系统设计的三次迭代]