NDK 知識梳理(3) JNI 之 Java 和 JNI 資料型別對映

澤毛發表於2017-12-21

一、前言

NDK程式設計時,當我們在Java層呼叫一個原生方法時,不可避免地要涉及到引數的傳遞,今天,我們就來一起學習一下如何在原生方法中解析從Java層傳遞過來的資料。

二、引數分類

我們根據Java當中的資料型別,將傳遞的引數分為以下三類。

2.1 基本資料型別

對於Java,其基本資料型別有八類,這八類基本資料型別在分別和JNI中的jxxx八類基本資料型別相對應,對應關係為:

NDK 知識梳理(3)   JNI 之 Java  和 JNI 資料型別對映
通過檢視jni.hjni_md.h標頭檔案,會發現jxxx其實是對於C/C++中基本資料型別的巨集定義:

# (1) jint
typedef int jint;
# (2) jlong
#ifdef _LP64
typedef long jlong;
#else
typedef long long jlong;
#endif
# (3) jbyte
typedef signed char jbyte;
# (4) jboolean
typedef unsigned char   jboolean;
# (5) jchar
typedef unsigned short  jchar;
# (6) jshort
typedef short           jshort;
# (7) jfloat
typedef float           jfloat;
# (8) jdouble
typedef double          jdouble;
複製程式碼

這八類基本資料型別的特點是:我們可以在JNI的原生函式中直接訪問。

2.2 引用型別

對於Java當中的引用型別,它們對映到JNI中,都是作為jobject的子類:

  • jclassClass位元組碼物件
  • jthrowable:異常
  • jstring:字串
  • jarray:陣列,根據陣列元素型別的不同,jarray又衍生出九種子類,也就是八種基本資料型別加上引用型別。

NDK 知識梳理(3)   JNI 之 Java  和 JNI 資料型別對映

它們在jni.h中的定義為:

# (1)
class _jobject {};
# (1)
class _jclass : public _jobject {};
# (2)
class _jthrowable : public _jobject {};
# (3) 
class _jstring : public _jobject {};
# (4)
class _jarray : public _jobject {};
class _jbooleanArray : public _jarray {};
class _jbyteArray : public _jarray {};
class _jcharArray : public _jarray {};
class _jshortArray : public _jarray {};
class _jintArray : public _jarray {};
class _jlongArray : public _jarray {};
class _jfloatArray : public _jarray {};
class _jdoubleArray : public _jarray {};
class _jobjectArray : public _jarray {};
複製程式碼

和基本資料型別不同,對於引用型別的訪問需要通過JNI提供的方法。

三、例項講解

下面我們用一個例項來講解每一種型別的訪問方式。

3.1 基本資料型別

從上面的程式碼可以看出,從Java方法到Native方法,除了前面兩個引數,都是一一對應的,前面兩個引數的含義為:

  • JNIEnv*:第一個引數是一個指向JVM函式表的指標,函式表中的每一個入口指向一個JNI函式,我們可以通過這些函式去訪問JVM中的資料結構。
  • jobject/jclass:第二個引數的型別取決於在JavaNative方法的型別:
  • 如果是一個普通方法,那麼引數型別為jobject,引數含義為呼叫Native方法的例項。
  • 如果是一個static方法,引數型別為jclass,引數含義為呼叫Native方法的Class物件。

3.2 引用型別

對於所有的引用型別,JNIJava中的所有物件當作一個C指標傳遞到本地方法中,這個指標指向JVM中的內部資料結構,而對於該資料結構的訪問需要通過第一個引數JNIEnv*函式表所提供的函式來訪問,下面,我們就來介紹這四種型別的基本訪問。

3.2.1 字串

對於字串,我們可以分為以下幾類: **(1) **

3.2.2 Class 位元組碼物件

3.2.3 陣列

3.2.4 異常

相關文章