• 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
    ", (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;
    假设对unio类型不太明确的同学,请參考相关资料,在这里不细讲。



  • 相关阅读:
    c++读写MySQL
    感叹游戏行业的飞速发展
    和真正的程序员在一起是怎样的体验
    程序媛是怎样找老公的
    IO和socket编程
    郁金香搜索引擎的方案
    实现一个自己的搜索引擎的初始规划
    JVM知识在离线数据中的运用
    看Lucene源码必须知道的基本规则和算法
    看Lucene源码必须知道的基本概念
  • 原文地址:https://www.cnblogs.com/cynchanpin/p/7136178.html
Copyright © 2020-2023  润新知