首页 > 代码库 > JNI/NDK开发指南(三)——JNI数据类型及与Java数据类型的映射关系
JNI/NDK开发指南(三)——JNI数据类型及与Java数据类型的映射关系
转载请注明出处:http://blog.csdn.net/xyang81/article/details/42047899
当我们在调用一个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, "test", obj, new MyClass(), new int[] {}); } static { System.loadLibrary("HelloWorld"); } }
在HelloWorld.java中定义了一个test的native方法,该方法中一个共有12个参数,其中前面8个为基本数据类型,后面4个全部为引用类型。
HelloWorld.class生成的头文件内容:
/* * Class: com_study_jnilearn_HelloWorld * Method: test * Signature: (SIJFDCZBLjava/lang/String;Ljava/lang/Object;)V */ JNIEXPORT void JNICALL Java_com_study_jnilearn_HelloWorld_test (JNIEnv *, jclass, jshort, jint, jlong, jfloat, jdouble, jchar, jboolean, jbyte, jstring, jobject, jobject);
从头文件函数的原型可以得知,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表示,jobject有很多子类:jstring、jclass、jthrowable、jarray,其中jarray有8个子类,分别对应Java中的8种基本数据类型(jintArray、jshortArray、jlongArray等),由于字符串在开发当中经常用到,所以Java中的String类型在JNI中用jstring表示。下面再回顾头来看看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;如果对unio类型不太明白的同学,请参考相关资料,在这里不细讲。
JNI/NDK开发指南(三)——JNI数据类型及与Java数据类型的映射关系