(4.1.27.5) JNI/NDK开发指南(二)——JNI数据类型及与Java数据类型的映射关系
来源:互联网 发布:黑龙江大数据产业联盟 编辑:程序博客网 时间:2024/05/20 10:14
当我们在调用一个Java native方法的时候,方法中的参数是如何传递给C/C++本地函数中的呢?
Java方法中的参数与C/C++函数中的参数,它们之间是怎么转换的呢?
我猜你应该也有相关的疑虑吧,咱们先来看一个例子,还是以HelloWorld为例:
HelloWorld.java:
- package com.study.jnilearn;
- class MyClass {}
- public class HelloWorld {
- public static native void test(short s, int i, long l, float f, double d, char c,
- boolean z, byte b, String str, Object obj, MyClass p, int[] arr);
- public static void main(String[] args) {
- String obj = "obj";
- short s = 1;
- long l = 20;
- byte b = 127;
- test(s, 1, l, 1.0f, 10.5, 'A', true, b, "中国", obj, new MyClass(), new int[] {});
- }
- static {
- System.loadLibrary("HelloWorld");
- }
- }
在HelloWorld.java中定义了一个test的native方法,该方法中一个共有12个参数,其中前面8个为基本数据类型,后面4个全部为引用类型。
由HelloWorld.class生成的native函数原型及实现:
- /*
- * Class: com_study_jnilearn_HelloWorld
- * Method: test
- * Signature: (SIJFDCZBLjava/lang/String;Ljava/lang/Object;Lcom/study/jnilearn/MyClass;[I)V
- */
- JNIEXPORT void JNICALL Java_com_study_jnilearn_HelloWorld_test
- (JNIEnv *env, jclass cls, jshort s, jint i, jlong l, jfloat f,
- jdouble d, jchar c, jboolean z, jbyte b, jstring j_str, jobject jobj1, jobject job2, jintArray j_int_arr)
- {
- printf("s=%hd, i=%d, l=%ld, f=%f, d=%lf, c=%c, z=%c, b=%d", s, i, l, f, d, c, z, b);
- const char *c_str = NULL;
- c_str = (*env)->GetStringUTFChars(env, j_str, NULL);
- if (c_str == NULL)
- {
- return; // memory out
- }
- (*env)->ReleaseStringUTFChars(env, j_str, c_str);
- printf("c_str: %s\n", (char*)c_str);
- }
调用test方法的输出结果:
从头文件函数的原型可以得知,test方法中形参的数据类型自动转换成了JNI中相应的数据类型,不难理解,在调用Java native方法将实参传递给C/C++函数的时候,会自动将java形参的数据类型自动转换成C/C++相应的数据类型,所以我们在写JNI程序的时候,必须要明白它们之间数据类型的对应关系。
在Java语言中数据类型分为基本数据类型和引用类型,其中基本数据类型有8种:byte、char、short、int、long、float、double、boolean,除了基本数据类型外其它都是引用类型:Object、String、数组等。8种基本数据类型分别对应JNI数据类型中的jbyte、jchar、jshort、jint、jlong、jfloat、jdouble、jboolean。所有的JNI引用类型全部是jobject类型,为了使用方便和类型安全,JNI定义了一个引用类型集合,集合当中的所有类型都是jobject的子类,这些子类和Java中常用的引用类型相对应。例如:jstring表示字符串、jclass表示class字节码对象、jthrowable表示异常、jarray表示数组,另外jarray派生了8个子类,分别对应Java中的8种基本数据类型(jintArray、jshortArray、jlongArray等)。下面再回顾头来看看test方法与Java_com_study_jnilearn_HelloWorld_test函数中参数类型的对应关系:
- // HelloWorld.java
- public static native void test(short s, int i, long l, float f, double d, char c,
- boolean z, byte b, String str, Object obj, MyClass p);
- // HelloWorld.h
- JNIEXPORT void JNICALL Java_com_study_jnilearn_HelloWorld_test
- (JNIEnv *, jclass, jshort, jint, jlong, jfloat, jdouble, jchar, jboolean, jbyte, jstring, jobject, jobject, jintArray);
从上面两个函数的参数中可以看出来,除了JNIEnv和jclass这两个参数外,其它参数都是一一对应的。下面是JNI规范文档中描述Java与JNI数据类型的对应关系:
基本数据类型:
引用类型:
注意:
1、JNI如果使用C++语言编写的话,所有引用类型派生自jobject,使用C++的继承结构特性,使用相应的类型。如下所示:
- class _jobject {};
- class _jclass : public _jobject {};
- class _jstring : public _jobject {};
- class _jarray : public _jobject {};
- class _jbooleanArray : public _jarray {};
- class _jbyteArray : public _jarray {};
- ...
2、JNI如果使用C语言编写的话,所有引用类型使用jobject,其它引用类型使用typedef重新定义,如:typedef jobject jstring
jvalue类型:
jvalue是一个unio(联合)类型,在C语中为了节约内存,会用联合类型变量来存储声明在联合体中的任意类型数据。在JNI中将基本数据类型与引用类型定义在一个联合类型中,表示用jvalue定义的变量,可以存储任意JNI类型的数据,后面会介绍jvalue在JNI编程当中的应用。原型如下:
- typedef union jvalue {
- jboolean z;
- jbyte b;
- jchar c;
- jshort s;
- jint i;
- jlong j;
- jfloat f;
- jdouble d;
- jobject l;
- } jvalue;
原文地址:http://blog.csdn.net/xyang81/article/details/42047899
- (4.1.27.5) JNI/NDK开发指南(二)——JNI数据类型及与Java数据类型的映射关系
- JNI/NDK开发指南(三)——JNI数据类型及与Java数据类型的映射关系
- JNI/NDK开发指南(三)——JNI数据类型及与Java数据类型的映射关系
- JNI/NDK开发指南(三)——JNI数据类型及与Java数据类型的映射关系
- JNI/NDK开发指南(三)——JNI数据类型及与Java数据类型的映射关系
- JNI/NDK开发指南(三)——JNI数据类型及与Java数据类型的映射关系
- NDK开发 - JNI数据类型与Java数据类型映射关系
- JNI 数据类型与 Java 数据类型的映射关系
- JNI/NDK开发指南(二)——JVM查找java native方法的规则
- JNI/NDK开发指南(二)——JVM查找java native方法的规则
- JNI/NDK开发指南(二)——JVM查找java native方法的规则
- JNI/NDK开发指南(二)——JVM查找java native方法的规则
- JNI/NDK开发指南(二)——JVM查找java native方法的规则
- (4.1.27.8)JNI/NDK开发指南(五)——Jni打包及引用aar
- Java 数据类型与jni数据类型对应关系
- NDK开发(三):JNI数据类型的详解
- JNI/NDK开发指南(二)
- JNI/NDK开发指南(一)—— JNI开发流程及HelloWorld
- hibernate集合映射inverse和cascade详解
- Android 6.0: 动态权限管理的解决方案
- webstorm快捷键整理
- delphi 多线程定时执行程序如何写
- 转自wangdinghai的博客,数据库恢复
- (4.1.27.5) JNI/NDK开发指南(二)——JNI数据类型及与Java数据类型的映射关系
- Meteor 中使用mysql(查询)
- 设计模式之一简单工厂模式
- redis 基础入门
- bzoj3309: DZY Loves Math
- iOS项目代码行数统计
- eclipse 下tomcat加载两次程序的解决办法
- gnocchi-采样数据存储流程分析(002)--数据的异步统计
- Object-C之KVC与KVO