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, "中国", 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数据类型的相应关系:
基本数据类型:
引用类型:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveHlhbmc4MQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
注意:
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数据类型的映射关系的更多相关文章
- JNI/NDK开发指南(二)——JVM查找java native方法的规则
		通过第一篇文章,大家明白了调用native方法之前,首先要调用System.loadLibrary接口加载一个实现了native方法的动态库才能正常访问,否则就会抛出java.lang.Unsatis ... 
- JNI/NDK开发指南(开山篇)
		转载请注明出处:http://blog.csdn.net/xyang81/article/details/41759643 相信很多做过Java或Android开发的朋友经常会接触到JNI方面的技术, ... 
- JNI/NDK开发指南(四)——字符串处理
		转载请注明出处:http://blog.csdn.net/xyang81/article/details/42066665 从第三章中能够看出JNI中的基本类型和Java中的基本类型都是一一相应的,接 ... 
- JNI/NDK开发指南(一)—— JNI开发流程及HelloWorld
		转载请注明出处:http://blog.csdn.net/xyang81/article/details/41777471 JNI全称是Java Native Interface(Java本地接口)单 ... 
- JNI/NDK开发指南(九)——JNI调用性能測试及优化
		转载请注明出处:http://blog.csdn.net/xyang81/article/details/44279725 在前面几章我们学习到了.在Java中声明一个native方法,然后生成本地接 ... 
- JNI/NDK开发指南(十)——JNI局部引用、全局引用和弱全局引用
		转自:http://blog.csdn.net/xyang81/article/details/44657385 这篇文章比较偏理论,详细介绍了在编写本地代码时三种引用的使用场景和注意事项.可能看 ... 
- JNI/NDK开发指南(2)
		1.生成动态库.so,存放于手机的system/lib/中(APP怎样将.so存入该文件夹,奇怪?????),Java层调用JNI的类会运行静态代码System.loadLibrary("* ... 
- Android JNI/NDK开发教程
		JNI/NDK开发指南:http://blog.csdn.net/xyang81/article/details/41759643 
- JNI/NDK开发
		公司的新需求终于解决完了,离测试和发布还有段时间,第一次体验了下没需求没bug的感觉,真是舒爽~然后翻了翻有什么可以学的.无意翻到了Android后期发展的五大趋势.一.性能优化.二.高级UI.三.J ... 
随机推荐
- ES6 学习笔记 - let和const
			let 和 const 命令 学习资料:ECMAScript 6 入门 let 所声明的变量,只在let命令所在的代码块内有效.用途:循环计数器. 如果使用var,只有一个全局变量i: var a = ... 
- 关于c++11中static类对象构造函数线程安全的验证
			在c++11中,static静态类对象在执行构造函数进行初始化的过程是线程安全的,有了这个特征,我们可以自己动手轻松的实现单例类,关于如何实现线程安全的单例类,请查看c++:自己动手实现线程安全的c+ ... 
- My-Eclipse 快捷键大全
			Ctrl+1 快速修复(最经典的快捷键,就不用多说了) Ctrl+D: 删除当前行 Ctrl+Alt+↓ 复制当前行到下一行(复制增加) Ctrl+Alt+↑ 复制当前行到上一行(复制增加) Alt+ ... 
- Mybatis学习总结一
			一.Mybatis架构 JAR包下载地址 1. mybatis配置 SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息. mapper. ... 
- 微服务网关从零搭建——(九)网关部署到linux服务器
			环境准备 公司电脑已安装core环境所以此处略过core环境安装 可参看此处 consul安装 如果没有wget命令 执行以下命令 yum install wget 下载consul wget htt ... 
- JAVA学习笔记16——线程的创建和启动
			Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例.每个线程的作用是完成一定的任务,实际上就是执行一段程序流(一段顺序执行的代码).Java使用线程执行体来代表这段 ... 
- 【Js 文件】 相关
			防止浏览器缓存 <script src="/js/common.js?t=<%=DateTime.Now.ToFileTime().ToString()%>>&quo ... 
- 散列--P1047 校门外的树
			题目描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,-,L,都种有 ... 
- [LNOI2014]LCA(树链剖分)
			BZOJ传送门 Luogu传送门 题目:给你一棵树,给你n个询问,每个询问要求输出$\sum_{i=l}^{r}depth(LCA(i,z))$ 细看看其实没有想象的那么难 大体思路: 1.对于每个询 ... 
- <SpringMvc>入门三 参数绑定
			1.get请求 <%--请求参数的绑定--%> <%--get请求参数--%> <a href="/param/testParam1?username=tom& ... 
