Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android中關於JNI 的學習(二)對於JNI方法名,數據類型和方法簽名的一些認識

Android中關於JNI 的學習(二)對於JNI方法名,數據類型和方法簽名的一些認識

編輯:關於Android編程

我們知道,利用javah生成的c/c++頭文件的時候,會對java中定義的 native 函數生成對應的jni層函數,如下:

/* 
 * Class:     com_lms_jni_JniTest 
 * Method:    getTestString 
 * Signature: ()Ljava/lang/String; 
 */  
JNIEXPORT jstring JNICALL Java_com_lms_jni_JniTest_getTestString  
  (JNIEnv *, jobject);  

我們可以看到方法名是以Java_com_lms_jni等開頭的,還有什麼所謂的Signature,那這些其實都是什麼意思呢,今天我們就來簡單地認識一下。

JNI 命名規則

對於傳統的JNI編程來說,JNI方法跟Java類方法的名稱之間有一定的對應關系,要遵循一定的命名規則,如下:

1) 前綴: Java_
2) 類的全限定名,用下劃線進行分隔(_):com_lms_jni_JniTest
3) 方法名:getTestString
3) jni函數指定第一個參數: JNIEnv *
4) jni函數指定第二個參數: jobject
5) 實際Java參數: jstring, jint ....
6) 返回值的參數 : jstring, jint.... 所以對於在Java類 com.lms.jni.HwDemo中的一個方法:
public native String addTail(String tail);

其對應的jni層的方法如下:
jstring Java_com_lms_jni_HwDemo_addTail(JNIEnv * e, jobject clazz, jstring tail);

如果不這樣命名,當把動態庫加載進DVM的時候,通過JNIEnv *指針去查找Java Native方法對應的JNI方法的時候,就會找不到了。
注意,我們也可以利用函數注冊的方法,將Java層的方法名跟JNI層的方法名的對應關系保存起來,注冊到DVM中,就不需要這樣的命名規范了。

JNI 數據類型


我們知道Java的數據類型是跟C/C++的數據類型是不一樣的,而JNI是處於Java和Native本地庫(大部分是用C/C++寫的)中間的一層,JNI對於兩種不同的數據類型之間必須做一種轉換,所以在JNI跟Java之間就會有數據類型的對應關系。 在JNI中,提供了以下各種數據類型,可以分為原生類型和引用類型: 對於原生類型有:jchar, jbyte, jshort, jint, jlong, jfloat, jdouble, jboolean,其與java端的數據類型對應如下表:
java jni char jchar byte jbyte short jshort int jint long jlong float jfloat double jdouble boolean jboolean
對於引用類型則有:jobject, jstring, jthrowable, jclass, jarray, 以及繼承於jarray,對應於其原生類型的8種jarray和jobjectarray。

\

知道了不同的數據類型的轉換關系,我們就知道在什麼情況下,應該對數據進行怎麼樣的處理。

JNI方法簽名



為什麼會有方法簽名這種東西呢?這是因為Java這邊支持函數重載,即雖然參數不一樣,但是方法名一樣,那麼在JNI層它們的方法名都會是一樣的,那JNI也會犯迷糊了,得找哪個呢?
不過也正是因為其參數類型是不一樣的,所以就出現了方法簽名,利用方法簽名和方法名來唯一確定一個JNI函數的調用。
既然方法簽名是基於參數類型的不同而形成的,首先要知道Java各數據類型對應的簽名是什麼,也就是所謂的類型簽名,
在jni.h文件中就已經定義了這樣一套規則,如下:
typedef union jvalue {
    jboolean    z;
    jbyte       b;
    jchar       c;
    jshort      s;
    jint        i;
    jlong       j;
    jfloat      f;
    jdouble     d;
    jobject     l;
} jvalue;

對應於Java端的數據類型,我們也可以看一下下面的表:
Java 類型 類型簽名 boolean Z byte B char C short S int I long L float F double D 類 L全限定名;,比如String, 其簽名為Ljava/lang/util/String; 數組 [類型簽名, 比如 [B
對於上面的類,要注意其後面還有一個分號。
而對一個方法,其簽名就是其參數類型簽名和返回值類型簽名的字符串,其形式如下:
(類型簽名1類型簽名2...)返回值類型簽名
每個類型簽名之間是沒有空格的,下面看看兩個例子:

有方法 1):
public string addTail(String tail, int index)

其對應的簽名如下:
(Ljava/util/String;I)Ljava/util/String;

方法 2):
public int addValue(int index, String value,int[] arr)

其對應的簽名如下:
(ILjava/util/String;[I)I

相信通過這兩個例子,大家也能夠了解了方法簽名是什麼樣的形式了吧,對於JNI這些奇形怪狀的表示形式也有一定的了解了。

結束。
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved