`
iaiai
  • 浏览: 2145189 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JNI数据类型的详解

 
阅读更多
       在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 */
  • 大小: 105 KB
  • 大小: 53.4 KB
  • 大小: 345.3 KB
  • 大小: 88.4 KB
  • 大小: 88.6 KB
  • 大小: 91.1 KB
  • 大小: 107.4 KB
分享到:
评论

相关推荐

    jni数据类型转换

    jni数据类型转换例程 1. java向native传递常用基本数据类型 和字符串类型 2. java向native传递数组类型 3. java向native传递自定义java对象 4. java向native传递任意java对象(以向native传递ArrayList为例) 5....

    08_12_JNI_02_jni数据类型&属性方法

    08_12_JNI_02_jni数据类型&属性方法08_12_JNI_02_jni数据类型&属性方法08_12_JNI_02_jni数据类型&属性方法08_12_JNI_02_jni数据类型&属性方法08_12_JNI_02_jni数据类型&属性方法08_12_JNI_02_jni数据类型&属性方法08...

    Java与JNI数据类型对照表

    Java与JNI数据类型对照表,可能有许多不足之处,请大家参考一下。

    JNI数据类型.pdf

    JNI数据类型.pdf

    Java本地调用JNI使用规范详解.doc

    本文档主要讲述的是Java本地调用JNI使用规范详解;JNI概述;JavaNative Interface的缩写,中文为Java本地调用。从Java1.1开始,JNI即成为Java标准的一部分。 JNI设计的目的是为了允许Java代码与其他语言进行交互。但...

    JNI数据类型[借鉴].pdf

    JNI数据类型[借鉴].pdf

    Jni应用个人详解

    记得是刚毕业时研究的JNI技术,希望帮到大家

    JNI使用规范详解.pdf

    JNI,全称为Java Native Interface,即Java本地接口,JNI是Java调用Native 语言的一种特性。通过JNI可以使得Java与C/C++机型交互。即可以在Java代码中调用C/C++等语言的代码或者在C/C++代码中调用Java代码。由于JNI...

    jni数据传递demo

    jni基本数据类型,数组及对象的传递demo,此demo可推出c,c++调用java方法的实现原理

    JNI详解及实例程序(英文)

    JNI文档, 英文文档、示例程序及讲解、

    Android 深入研究JNI详解

    此时,VM扮演着桥梁的角色,让Java与C组件能通过标准的JNI介面而相互沟通。 应用层的Java类是在虚拟机(VM: Vitual Machine)上执行的,而C件不是在VM上执行,那么Java程式又如何要求VM去载入(Load)所指定的C组件呢?...

    Jni 项目 包含各种数据类型转换

    通过jni 用java调用c/c++ 编译的 dll 动态库 帖子地址 https://blog.csdn.net/qq_38777624/article/details/114625668

    java jni c++ 类型转换

    java jni 与 c++ 数据类型转换 及调用

    android jni常用函数详解

    总结了jni C C++中常用的函数的使用方法,并给出了实例源码。对于编写学习jni的人员有很大的帮助

    JNI与C++数据类型传递示例(包括ArrayList对象、ArrayList嵌套返回)

    一个C++(Ubuntu16.04+QT5.9.1)通过JNI,调用JAVA类及方法的示例。通过JNI传递和返回多种类型的参数,boolean ,int,String,ArrayList,ArrayList嵌套ArrayList&lt;ArrayList&lt;String&gt;&gt;等。

    android jni详解

    Android调用C++接口调用技术Java Native Interface(JNI)详解,

    JNI中C和Java参数传递详细例子

    JNI中C和Java参数传递详细例子,各种数据类型,基本类型,数据,结构体,DEMO,非常适合初学者,一看就明,详细例子

    JNI详解和操作指南

    JNI技术手册。JNI设计实践之路。android_jni操作指南。Android_JNI总结

Global site tag (gtag.js) - Google Analytics