今天,简单讲讲如何在jni内把结果返回给java端。

一。使用Integer类作为返回值参数传入jni。

最近在开发jni时,需要返回多个参数给java。这个过程中,碰到了一些问题,值得探讨一下。

 
具体是这样,jni方法jni_do_something作了底层处理后,得出两个int数据,需要将他们的值传递给java。在C语言中,直接用指针就可以了。Java中可以传递两个Integer的引用。用JNI怎么实现呢?
我在android frameworks源代码中看了一下,对于类似传值需求,android都是在java层自定义了一个class,用来封装各个需要传递的参数。jni中需要修改时,获得该class的成员id,然后用SetIntField来修改。
我不想这么做,因为类似的native方法比较多,我总不能每次都定义结构体吧,而且将不同方法的参数封装在一个class中,也不太对,因为它们没有共同意义。
为了让jni能修改,Java层毫无疑问需要传入Integer类型参数,这样jni才认为它是一个jobject,才可以修改。好的,问题出现了。jni方法实现:
jni_do_something(JNIEnv *env, jobject thiz, jobject p1, jobject p2)
{jclass c;jfieldID id;c = env->FindClass("java/lang/Integer");if (c==NULL){LOGD("FindClass failed");return -1;}id = env->GetFieldID(c, "value", "I");if (id==NULL){LOGD("GetFiledID failed");return -1;}env->SetIntField(p1, id, 5);env->SetIntField(p2, id, 10);return 0;
}

java层调用如果这样写:

native int do_something(Integer p1, Integer p2);Integer p1=0, p2=0;
do_something(p1, p2);
Log.d("test", "p1: "+p1);
Log.d("test", "p2: "+p2);

这样打印出的值是(10,10),而不是期望的(5,10)。为什么呢?

我在stackoverflow上发了一个贴,大家众说纷纭。有的说跟mutable/imutable object有关,有的说跟autoboxing有关。
我再次做了试验。如果写成
Integer p1=0, p2=1;

或者:

Integer p1 = new Integer(0);Integer p2 = new Integer(0);

原来,这跟autoboxing有关。当你用Integer p1 = 0这种方式时,java使用autoboxing机制将0封装在一个Integer对象中,这时使用了Integer类的valueOf方法。在java 语言中,有一个很诡异的现象,对于在-128~127间的小数字,会在static pool中返回一个静态对象,在这个范围外的,会new一个Integer。

二.使用int数组作为返回值传入jni。

JNIEXPORT jint JNICALL Java_com_p2p_h265_1api_HWH265_1GetWidth_1APIs_h264ParseSequenceParameterSet
(JNIEnv *env, jclass, jbyteArray pdata, jint nSps, jintArray out_4para, jint nsps_buf_offset){

其中out_4para是java端传入的新建的长度为2的数组。

int * para_size = (int*) (env)->GetIntArrayElements(out_4para, 0);
para_size[0] = params.pic_width;
para_size[1] = params.pic_height;
(env)->ReleaseIntArrayElements(out_4para, para_size, 0);

这样,java端就收到了jni传递的值。

android jni 返值就讲完了。

就这么简单。



android jni 返值相关推荐

  1. java jni 数据类型_【Android JNI】Native层解析Java复杂数据类型HashMap

    前提 Java HashMap 是基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用null值和null键.HashMap是存放引用类型数据的容器,只能存放引用数据类型,不能存 ...

  2. Android JNI原理分析

    引言:分析Android源码6.0的过程,一定离不开Java与C/C++代码直接的来回跳转,那么就很有必要掌握JNI,这是链接Java层和Native层的桥梁,本文涉及相关源码: frameworks ...

  3. Android JNI开发入门之一

    JNI在Android系统中有着广泛的应用.Android系统底层都是C/C++实现的,上层提供的API都是Java的,Java通过JNI调用底 层的实现.比如:Android API多媒体接口Med ...

  4. android jni malloc和free的使用

    今天,简单讲讲android在jni如何使用malloc和free进行内存的分配和释放. 这个其实也是C++相关的知识,不过jni需要用到,所以这里记录一下. 一.malloc()和free()的基本 ...

  5. android jni new/delete 和 new[]/delete[]

    今天,简单讲讲android里再jni使用new时如何释放内存. 这个其实是和C++有关的知识,不过jni编程时还是需要注意的.所以这里记录一下. new 和 delete 到底是什么? 如果找工作的 ...

  6. android jni 释放资源

    今天,简单讲讲android 如何释放在jni新建得 结构体等资源. 因为android里是自动释放资源的,所以之前没有注意这一点,后来查找资料才发现jni需要自己释放资源.这里记录一下. JNI 编 ...

  7. android jni 返回java类

    今天,简单讲讲android 在jni中如何返回一个java的类. 之前,我写了一些关于jni的博客,里面返回的都是简单的int类型,那么如果我需要返回很多int和String类型,那么怎么办呢?当然 ...

  8. android jni 将BYTE* 和 jbyteArray 之间的转换

     今天,简单讲讲如何在jni中将  BYTE* 转成 jbyteArray. 这个是我在做jni时碰到的问题.因为c传回的值是BYTE*,而返回给java代码是byte[],对应的jni的数据 ...

  9. android JNI层线程回调Java函数

    今天,简单讲讲android的jni如何使用jni回调java函数. 之前,我写了部分jni的博客,讲的都是如何从android的java代码调用jni的函数.最近,需要做一个新的功能,在jni的C函 ...

最新文章

  1. LINUX下用CTRL+R快速搜索HISTORY历史命令,快速索引到之前使用过的命令行语句
  2. 机器人抓矸石_基于机器视觉的多机械臂煤矸石分拣机器人系统研究
  3. c语言switch计算利润,求助。。关于用switch编写简易计算器
  4. go map的定义及使用
  5. MHA选择主库源码解析
  6. 浅谈C++类(6)--复制构造函数
  7. python 可视化_Python数据可视化
  8. 保存查看翻译:Thrift: Scalable Cross-Language Services Implementation中文翻译(Thrift:Œ可扩展的跨语言服务实现)...
  9. 基于队列的迷宫求解实现
  10. 【调试手段】linux下valgrind内存泄露检查
  11. JMeter录制的两种方法
  12. 解决导入Beautifulsoup 报错 AttributeError: 'module' object has no attribute '_base'的问题
  13. http接口开发请求参数签名实用工具类
  14. cat3 utp是不是网线_CAT网线知识
  15. 日常学习笔记-RGB配色和颜色转换
  16. 阿里云ACP考试模拟题一
  17. 怎么把jpg转换成pdf方法
  18. 一封台积电离职工程师的信
  19. via浏览器如何使用插件 Via浏览器添加使用插件教程
  20. stm32呼吸灯c语言程序,STM32使用PWM控制LED呼吸灯效果

热门文章

  1. javabean自定义组件
  2. php 时间函数参考
  3. 读CLR via C#总结(7) 以传引用的方式向方法传递参数---refout
  4. make的自动变量和预定义变量
  5. 每天改變或學習一點點 終究聚沙成塔
  6. Intellij IDEA + Maven + Cucumber 项目 (三):简单解释RunCukesTest.java
  7. Sublime Text3 3143 注册码,亲测可用!
  8. android style 中一些颜色的定义
  9. Aristochart – 灵活的 HTML5 Canvas 折线图
  10. 页面初始加载的是默认刷新一次(f5)