文档章节

jni数据类型

wangjian19
 wangjian19
发布于 2014/02/22 09:39
字数 1155
阅读 57
收藏 0
点赞 0
评论 0

       在Java中有两类数据类型:primitive types,如,int, float, char;另一种为reference types,如,类,实例,数组。


 注意:数组,不管是对象数组还是基本类型数组,都作为reference types存在,有专门的JNI方法取数组中每个元素。



1、void

java的void与JNI的void是一致的。


2、基本数据类型





3、对象类型



相比基本类型,对象类型的传递要复杂得多。不能对Jstring进行直接操作。

[java] view plaincopy

  1. //如下使用方式是错误的,因为jstring不同于C语言中的char *类型。  

  2. Java_com_conowen_test_testActivity_test(JNIEnv *env, jobject obj, jstring str)  

  3. {  

  4. /* ERROR: incorrect use of jstring as a char* pointer */  

  5. printf("%s", str);  

  6. ...  

  7. }  




注意:

[java] view plaincopy

  1. typedef jint jsize;  





3.1、GetStringUTFChars与ReleaseStringUTFChars函数简单说明(跳到3.2有更方便的函数)

        JNI支持Unicode/UTF-8字符编码互转。Unicode以16-bits值编码;UTF-8是一种以字节为单位变长格式的字符编码,并与7- bitsASCII码兼容。UTF-8字串与C字串一样,以NULL('\0')做结束符, 当UTF-8包含非ASCII码字符时,以'\0'做结束符的规则不变。7-bit ASCII字符的取值范围在1-127之间,这些字符的值域与UTF-8中相同。当最高位被设置时,表示多字节编码。


[java] view plaincopy

  1. //调用GetStringUTFChars,把一个Unicode字串转成UTF-8格式字串  

  2.   

  3. Java_com_conowen_test_testActivity_test(JNIEnv *env, jobject obj, jstring str)  

  4. {  

  5. char buf[128];  

  6. const jbyte *cbyte;  

  7. cbyte= (*env)->GetStringUTFChars(env, str, NULL);  

  8. if (cbyte== NULL) {  

  9. return NULL;  

  10. }  

  11. printf("%s", cbyte);  

  12. (*env)->ReleaseStringUTFChars(env, str, cbyte);  

  13.   

  14. scanf("%127s", buf);  

  15. return (*env)->NewStringUTF(env, buf);  

  16.   

  17. //或者return (*env)->NewStringUTF(env, "hello world");  

  18.  }  

         上述函数中,有isCopy参数,当该值为JNI_TRUE,将返回str的一个拷贝;为JNI_FALSE将直接指向str的内容。 注意:当isCopy为JNI_FALSE,不要修改返回值,不然将改变java.lang.String的不可变语义。一般会把isCopy设为 NULL,不关心Java VM对返回的指针是否直接指向java.lang.String的内容。

         注意:在调用GetStringChars之后,一定要调用ReleaseStringChars做释放,(Unicode -> UTF-8转换的原因)。不管在调用GetStringChars时为isCopy赋值JNI_TRUE还是JNI_FALSE,因不同JavaVM实现 的原因,ReleaseStringChars可能释放内存,也可能释放一个内存占用标记。

 

 3.2、GetStringRegion/GetStringUTFRegion函数简单说明

 

 因为这两个函数不涉及内存操作,所以较GetStringUTFChars使用要简单。也不用进行释放指针之类的操作,非常方便。(推荐使用)


[java] view plaincopy

  1. Java_com_conowen_test_testActivity_test(JNIEnv *env, jobject obj, jstring str)  

  2. {  

  3.   

  4. char outputbuf[128], inputbuf[128];  

  5. int len = (*env)->GetStringLength(env, str);  

  6. (*env)->GetStringUTFRegion(env, str, 0, len, outbuf);  

  7. printf("%s", outputbuf);  

  8. scanf("%s", inputbuf);  

  9. return (*env)->NewStringUTF(env, inbuf);  

  10. }  


GetStringUTFRegion有两个主要的参数,start 和 length, 这两个参数以Unicode编码计算. 该函数会做边界检查,所以可能抛出StringIndexOutOfBoundsException。 


3.3、GetStringLength/GetStringUTFLength函数简单说明


前者是Unicode编码长度,后者返回的是是UTF编码长度。


4、数组类型





JNI对每种数据类型的数组都有对应的函数。


4.1、常见错误操作:

[java] view plaincopy

  1. /* 直接操作数组是错误的 */  

  2. Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr)  

  3. {  

  4. int i, sum = 0;  

  5. for (i = 0; i < 10; i++) {  

  6. sum += arr[i];  

  7. }  

  8. }  


4.2、使用

void Get<Type>ArrayRegion(JNIEnv *env,<ArrayType> array, jsize start,jsize len, <NativeType> *buf);

进行操作

参数说明:

env: the JNIEnv interface pointer.

array: a reference to an array whose elements are to be copied.将要被拷贝的目标数组<ArrayType>

start: the starting index of the array elements to be copied.(数组的起始位置)

len: the number of elements to be copied.(拷贝元素的个数)buf:the destination buffer.存放结果的本地数组<NativeType>

返回值:void



[java] view plaincopy

  1. Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr)  

  2. {  

  3. jint buf[10];  

  4. jint i, sum = 0;  

  5. (*env)->GetIntArrayRegion(env, arr, 0, 10, buf);  

  6. for (i = 0; i < 10; i++) {  

  7. sum += buf[i];  

  8. }  

  9. return sum;  

  10. }  

  11.   

  12. JNI中数组的基类为jarray,其他如jintArray都是继承自jarray。  



4.3、使用<NativeType> *Get<Type>ArrayElements(JNIEnv *env,<ArrayType> array, jboolean *isCopy);进行数组操作



参数说明:

env: the JNIEnv interface pointer.array: a reference to the primitive array whose elements are tobe accessed.(目标数组)

isCopy: a pointer to a jboolean indicating whether a function

返回值:返回指向Java数组的一个直接的指针


[java] view plaincopy

  1. 使用实例:  

  2.   

  3. Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr)  

  4. {  

  5. jint *carr;  

  6. jint i, sum = 0;  

  7. carr = (*env)->GetIntArrayElements(env, arr, NULL);  

  8. if (carr == NULL) {  

  9. return 0; /* exception occurred */  

  10. }  

  11. for (i=0; i<10; i++) {  

  12. sum += carr[i];  

  13. }  

  14. (*env)->ReleaseIntArrayElements(env, arr, carr, 0);  

  15. return sum;  

  16. }  

  17.   

  18.   

  19. )  


更多数组操作函数:

5、另外一些有用的宏定义(来自jni.h)



[java] view plaincopy

  1. #define JNI_FALSE   0  

  2. #define JNI_TRUE    1  

  3.   

  4. #define JNI_VERSION_1_1 0x00010001  

  5. #define JNI_VERSION_1_2 0x00010002  

  6. #define JNI_VERSION_1_4 0x00010004  

  7. #define JNI_VERSION_1_6 0x00010006  

  8.   

  9. #define JNI_OK          (0)         /* no error */  

  10. #define JNI_ERR         (-1)        /* generic error */  

  11. #define JNI_EDETACHED   (-2)        /* thread detached from the VM */  

  12. #define JNI_EVERSION    (-3)        /* JNI version error */  

  13.   

  14. #define JNI_COMMIT      1           /* copy content, do not free buffer */  

  15. #define JNI_ABORT       2           /* free buffer w/o copying back */ 


© 著作权归作者所有

共有 人打赏支持
wangjian19
粉丝 15
博文 50
码字总数 101397
作品 0
深圳
高级程序员
Android深入理解JNI(二)类型转换、方法签名和JNIEnv

相关文章 Android深入理解JNI系列 前言 上一篇文章介绍了JNI的基本原理和注册,这一篇接着带领大家来学习JNI的数据类型转换、方法签名和JNIEnv。 1.数据类型的转换 首先给出上一篇文章中and...

刘望舒 ⋅ 2017/07/03 ⋅ 0

Android NDK开发之Jni的数据类型

在前面的一篇博客《Android NDK开发简介》,我简单地说明了Android NDK开发的流程,以及其重要的一环:JNI层得开发。今天我再详细说明一下自己的学习经验。 JNI是Java代码和C/C++代码通信的桥...

zhiweiofli ⋅ 2013/03/15 ⋅ 0

JNI使用规范

一、 JNI概述 JavaNative Interface的缩写,中文为Java本地调用。从Java1.1开始,JNI即成为Java标准的一部分。 JNI设计的目的是为了允许Java代码与其他语言进行交互。但这样做通常会导致丧失...

云颖 ⋅ 2013/12/03 ⋅ 0

android源码-深入理解JNI技术

9/5/2016 2:10:30 PM android源码-深入理解JNI技术 本章涉及的源代码文件名及位置 AndroidRunTime.cpp (framework/base/core/jni/AndroidRunTime.cpp)JNIHelp.c (libnativehelper/JNIHelp.c)......

小米墨客 ⋅ 2016/09/07 ⋅ 3

Android平台上的JNI技术介绍

NDK简介 Android是由Google领导开发的操作系统,Android依靠其开放性,迅速普及,成为目前最流行的智能手机操作系统。 图0-1 Android系统架构图 图0-1是Android系统架构图。大多数程序位于最...

ChowJames ⋅ 2012/10/01 ⋅ 0

深入理解JNI

深入理解JNI 本章主要内容 · 通过一个实例,介绍JNI技术和在使用中应注意的问题。 本章涉及的源代码文件名及位置 下面是本章分析的源码文件名及其位置。 · MediaScanner.java framework/ba...

xiaole0313 ⋅ 2016/03/31 ⋅ 0

[深入理解Android卷一 全文-第二章]深入理解JNI

由于《深入理解Android 卷一》和《深入理解Android卷二》不再出版,而知识的传播不应该因为纸质媒介的问题而中断,所以我将在OSC博客中全文转发这两本书的全部内容。 第2章 深入理解JNI 本章...

邓凡平 ⋅ 2015/08/02 ⋅ 0

NDK开发系列之——Jni数据类型

在NDK开发调用jni函数时,信息基本都是通过数据传递来实现。而且jni接口特别高冷,只要稍微 哪里不对,就会崩溃,把人都要整崩溃。我刚开始就时不时因为一个字母大小写错了,少写一个分号,怎...

翻滚吧李博 ⋅ 2017/12/08 ⋅ 0

Android OpenGL开发目录

Android OpenGL开发目录 Android OpenGL开发1--VS2017+OpenGL环境的配置 to be continued... 其它目录 Android NDK开发之旅 目录 Android NDK开发之旅1--NDK介绍 Android NDK开发之旅2--C语言...

香沙小熊 ⋅ 01/07 ⋅ 0

JNI 之二 :java & c/c++ 相互通信及调用

JNI是Java Native Interface的缩写,JNI是一种机制,有了它就可以在java程序中调用其他native代码,或者使native代码调用java层的代码。也就是说,有了JNI我们可以使Android项目中,java层与...

LiSteven ⋅ 2013/04/01 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

数据结构与算法之双向链表

一、双向链表 1.双向链表的结点结构 typedef struct DualNode{ ElemType data; struct DualNode *prior; // 前驱结点 struct DualNode *next; // 后继结点}DualNode, *DuL...

aibinxiao ⋅ 20分钟前 ⋅ 0

五大最核心的大数据技术

大数据技术有5个核心部分,数据采集、数据存储、数据清洗、数据挖掘、数据可视化。关于这5个部分,有哪些核心技术?这些技术有哪些潜在价值?看完今天的文章就知道了。 大数据学习群:7165810...

董黎明 ⋅ 21分钟前 ⋅ 0

PhpStorm 头部注释、类注释和函数注释的设置

首先,PhpStorm中文件、类、函数等注释的设置在:setting-》Editor-》FIle and Code Template-》Includes下设置即可,其中方法的默认是这样的: /**${PARAM_DOC}#if (${TYPE_HINT} != "v...

nsns ⋅ 21分钟前 ⋅ 0

spring.net AOP

http://www.springframework.net/doc-latest/reference/html/aop-quickstart.html https://www.cnblogs.com/wujy/archive/2013/04/06/3003120.html...

whoisliang ⋅ 26分钟前 ⋅ 0

【HAVENT原创】创建 Dockerfile 生成新的镜像,并发布到 DockerHub

注意:Win7 与 Win10 的版本存在差异,Win7 版本使用 Docker Quickstart Terminal 进入控制台,Win10下面直接用管理员权限打开控制台或者 PowerShell 即可;另外 Win7 下面只能访问 C盘,/ap...

HAVENT ⋅ 26分钟前 ⋅ 0

pom.xml出现web.xml is missing ...解决方案

提示信息应该能看懂。也就是缺少了web.xml文件,<failOnMissingWebXml>被设置成true了。 搜索了一下,Stack Overflow上的答案解决了问题,分享一下。 目前被顶次数最多的回答原文如下: This...

源哥L ⋅ 27分钟前 ⋅ 0

js时间戳与日期格式之间相互转换

1. 将时间戳转换成日期格式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 // 简单的一句代码 var date = new Date(时间戳); //获取一个时间对象 /** 1. 下面是获取时间日期的方法,需要什么样的格式自己...

Jack088 ⋅ 32分钟前 ⋅ 0

web添加log4j

添加xml配置log4j.properties # Global logging configuration---root日志设置#log4j.rootLogger=info,dailyRollingFile,stdoutlog4j.rootLogger=debug,stdout,dailyRollingFile---......

黄柳淞 ⋅ 33分钟前 ⋅ 0

如何解决生产环境宕机问题

写在前面:该篇宕机问题的排查难度远比上一篇(记一次解决线上OOM的心路历程)大的太多,上一篇中内存泄漏的问题是有迹可循的,本次的宕机在业务日志上没有任何征兆,另外本文有许多值得深挖...

寰宇01 ⋅ 45分钟前 ⋅ 0

Redis查漏补缺:最易错过的技术要点大扫盲

作者介绍 孤独烟,中国平安研发工程师,目前负责规则云平台架构设计以及需求研发工作。毕业后一直从事Java开发工作,在Web开发、架构设计上有多年的实战经验。在MySQL性能优化、JVM调优、分布...

kim_o ⋅ 46分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部