JNI-数据类型
转载:http://blog.csdn.net/conowen/article/details/7523145
在Java中有两类数据类型:primitive types,如,int, float, char;另一种为reference types,如,类,实例,数组。
注意:数组,不管是对象数组还是基本类型数组,都作为reference types存在,有专门的JNI方法取数组中每个元素。
1、void
java的void与JNI的void是一致的。
2、基本数据类型
3、对象类型
相比基本类型,对象类型的传递要复杂得多。不能对Jstring进行直接操作。
- //如下使用方式是错误的,因为jstring不同于C语言中的char *类型。
- Java_com_conowen_test_testActivity_test(JNIEnv *env, jobject obj, jstring str)
- {
- /* ERROR: incorrect use of jstring as a char* pointer */
- printf("%s", str);
- ...
- }
注意:
- 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中相同。当最高位被设置时,表示多字节编码。
- //调用GetStringUTFChars,把一个Unicode字串转成UTF-8格式字串
- Java_com_conowen_test_testActivity_test(JNIEnv *env, jobject obj, jstring str)
- {
- char buf[128];
- const jbyte *cbyte;
- cbyte= (*env)->GetStringUTFChars(env, str, NULL);
- if (cbyte== NULL) {
- return NULL;
- }
- printf("%s", cbyte);
- (*env)->ReleaseStringUTFChars(env, str, cbyte);
- scanf("%127s", buf);
- return (*env)->NewStringUTF(env, buf);
- //或者return (*env)->NewStringUTF(env, "hello world");
- }
上述函数中,有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_com_conowen_test_testActivity_test(JNIEnv *env, jobject obj, jstring str)
- {
- char outputbuf[128], inputbuf[128];
- int len = (*env)->GetStringLength(env, str);
- (*env)->GetStringUTFRegion(env, str, 0, len, outbuf);
- printf("%s", outputbuf);
- scanf("%s", inputbuf);
- return (*env)->NewStringUTF(env, inbuf);
- }
GetStringUTFRegion有两个主要的参数,start 和 length, 这两个参数以Unicode编码计算. 该函数会做边界检查,所以可能抛出StringIndexOutOfBoundsException。
3.3、GetStringLength/GetStringUTFLength函数简单说明
前者是Unicode编码长度,后者返回的是是UTF编码长度。
4、数组类型
JNI对每种数据类型的数组都有对应的函数。
4.1、常见错误操作:
- /* 直接操作数组是错误的 */
- Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr)
- {
- int i, sum = 0;
- for (i = 0; i < 10; i++) {
- sum += arr[i];
- }
- }
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_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr)
- {
- jint buf[10];
- jint i, sum = 0;
- (*env)->GetIntArrayRegion(env, arr, 0, 10, buf);
- for (i = 0; i < 10; i++) {
- sum += buf[i];
- }
- return sum;
- }
- 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_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr)
- {
- jint *carr;
- jint i, sum = 0;
- carr = (*env)->GetIntArrayElements(env, arr, NULL);
- if (carr == NULL) {
- return 0; /* exception occurred */
- }
- for (i=0; i<10; i++) {
- sum += carr[i];
- }
- (*env)->ReleaseIntArrayElements(env, arr, carr, 0);
- return sum;
- }
- )
更多数组操作函数:
5、另外一些有用的宏定义(来自jni.h)
- #define JNI_FALSE 0
- #define JNI_TRUE 1
- #define JNI_VERSION_1_1 0x00010001
- #define JNI_VERSION_1_2 0x00010002
- #define JNI_VERSION_1_4 0x00010004
- #define JNI_VERSION_1_6 0x00010006
- #define JNI_OK (0) /* no error */
- #define JNI_ERR (-1) /* generic error */
- #define JNI_EDETACHED (-2) /* thread detached from the VM */
- #define JNI_EVERSION (-3) /* JNI version error */
- #define JNI_COMMIT 1 /* copy content, do not free buffer */
- #define JNI_ABORT 2 /* free buffer w/o copying back */
JNI-数据类型的更多相关文章
- JNI数据类型(转)
本文原创,转载请注明出处:http://blog.csdn.net/qinjuning 在Java存在两种数据类型: 基本类型 和 引用类型 ,大家都懂的 . 在JNI的世界里也存在类似的数据类型,与 ...
- [转]jni数据类型映射、域描述符说明
在Java存在两种数据类型: 基本类型 和 引用类型 ,大家都懂的 . 在JNI的世界里也存在类似的数据类型,与Java比较起来,其范围更具严格性,如下: 1.primitive types ---- ...
- 006android初级篇之jni数据类型映射
JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++) 使用JNI的副作用 一旦使用JNI,JAVA程序就丧失了JAV ...
- JNI/NDK开发指南(三)——JNI数据类型及与Java数据类型的映射关系
转载请注明出处:http://blog.csdn.net/xyang81/article/details/42047899 当我们在调用一个Java native方法的时候.方法中的參数是怎样传递给C ...
- NDK学习笔记-JNI数据类型和属性方法的访问
JNI实现了C/C++与Java的相互访问,那么这篇文章就从C/C++访问Java开始说起 native函数说明 每个native函数,都至少有两个参数(JNIEnv *和jclass或jobject ...
- JNI实战(三):JNI 数据类型映射
在JNI实战(二):Java 调用 C 我们了解了JNI的静态注册和动态注册.也知道我们应该使用动态注册来进行JNI函数与Java方法之间的映射. 示例的映射表的数组为如下: static JNINa ...
- Android JNI 学习(三):JNI 数据类型和数据结构
本文我们来讨论一下JNI如何将Java类型映射到本机C类型. 一.基本数据类型 如下图表整理了Java基本类型和native对应的关系: Java类型 Native类型 描述 boolean jboo ...
- Android的NDK开发(3)————JNI数据类型的详解
在Java中有两类数据类型:primitive types,如,int, float, char:另一种为reference types,如,类,实例,数组. 注意:数组,不管是对象数组还是基本类型数 ...
- 基于 Android NDK 的学习之旅-----JNI 数据类型
经典老套流程,学编程语言东西,先学它最基础的数据类型,JNI也是如此.JNI 定义了一系列基本数据类型和引用数据类型与java想对应. 1.基本数据类型 下面一张表是描述了 Java 基本数据类型和J ...
- Android有关JNI 学习(两)为JNI方法名称,数据类型和方法签名的一些知识
我们知道,使用javah产生c/c++当在头文件,将java定义 native 功能,以产生相应jni层功能,如下面: /* * Class: com_lms_jni_JniTest * Method ...
随机推荐
- HTML DOM与XML DOM之间,既有区别
http://kb.cnblogs.com/page/74971/ HTML文档可以使用Core API和HTML API两者: 而XML文档只能使用Core API. 换句话说,HTML与XML重叠 ...
- python 简单示例说明os.walk和os.path.walk的不同
import os,os.path def func(arg,dirname,names): for filespath in names: print os.path.join(dirname,fi ...
- Uploadify 控件上传图片 + 预览
jquery的Uploadify控件上传图片和预览使用介绍. 在简单的servlet系统中和在SSH框架中,后台处理不同的,在三大框架中图片预览时费了不少力气,所以下面将两种情况都介绍一下. 1,前台 ...
- 几种java通信(rmi,http,hessian,webservice)协议性能比较
一.综述 本文比较了RMI,Hessian,Burlap,Httpinvoker,web service等5种通讯协议的在不同的数据结构和不同数据量时的传输性能.RMI是java语言本身提供的通讯协议 ...
- Ubuntu忘记管理员密码
Ubuntu中不小心把管理员密码忘记了,真叫人头大. 现提供一个解决方案: 1.重启 Ubuntu 系统,按 Esc 进入GRUB 菜单界面,如下图: 2.选择recovery mode. (第二个) ...
- 大四实习准备3_java多线程
4.25.27无耻地懒散了.....26号陪女朋友去了.今天28号,继续加油! 2015-4-28 Java 多线程 (java中类不能多继承,可以多层继承:接口则都可以) 定义和创建: 方法一:继承 ...
- uyouo[]常棒的一篇关于innnodb next-key lock的文章
何登成的 MySQL 加锁处理分析 Innodb锁机制:Next-Key Lock 浅谈
- android MIPI屏 导航栏丢失
/**************************************************************************** * android MIPI屏 导航栏丢失 ...
- 我的WCF之旅(3):在WCF中实现双工通信
双工(Duplex)模式的消息交换方式体现在消息交换过程中,参与的双方均可以向对方发送消息.基于双工MEP消息交换可以看成是多个基本模式下(比如请求-回复模式和单项模式)消息交换的组合.双工MEP又具 ...
- 编写高效的C程序与C代码优化 via jobbole
http://blog.jobbole.com/82582/ 原文出处: codeproject 译文出处:CodingWu的博客 欢迎分享原创到伯乐头条