Android Studio NDK 入門教程(3)--Java與C++之間的型別簽名
概述
本文主要介紹Java與C++通訊時函式的簽名關係
方法簽名
我們可以在生成的標頭檔案中看到每個方法上面都有如下注釋:
/*
* Class: com_example_wastrel_hellojni_HelloJNI
* Method: getFormCString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_wastrel_hellojni_HelloJNI_getFormCString
(JNIEnv *, jclass);
其中前兩個註釋很容易理解,第三個就是方法簽名,為什麼會有方法簽名這種東西呢?
這是因為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 | J |
float | F |
double | D |
void | V |
類 | L全限定名; |
陣列 | [型別簽名 |
注意:上面的類後面是有一個分號的。
如何計算一個方法的型別簽名
Java函式的型別簽名是根據函式的引數型別以及返回型別所決定的,引數型別放在括號裡面返回型別緊跟在括號外。
//native測試方法宣告
public static native String getFormCString();
//三個過載方法
public static native int TypeTest(boolean a,short b,long c,char d);
public static native Objects TypeTest(Date date,byte []m,HelloJNI k);
public static native Long Test(Character k,Double m);
//執行生成標頭檔案命令
/*
* Class: com_example_wastrel_hellojni_HelloJNI
* Method: getFormCString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_wastrel_hellojni_HelloJNI_getFormCString
(JNIEnv *, jclass);
/*
* Class: com_example_wastrel_hellojni_HelloJNI
* Method: TypeTest
* Signature: (ZSJC)I
*/
JNIEXPORT jint JNICALL Java_com_example_wastrel_hellojni_HelloJNI_TypeTest__ZSJC
(JNIEnv *, jclass, jboolean, jshort, jlong, jchar);
/*
* Class: com_example_wastrel_hellojni_HelloJNI
* Method: TypeTest
* Signature: (Ljava/util/Date;[BLcom/example/wastrel/hellojni/HelloJNI;)Ljava/util/Objects;
*/
JNIEXPORT jobject JNICALL Java_com_example_wastrel_hellojni_HelloJNI_TypeTest__Ljava_util_Date_2_3BLcom_example_wastrel_hellojni_HelloJNI_2
(JNIEnv *, jclass, jobject, jbyteArray, jobject);
/*
* Class: com_example_wastrel_hellojni_HelloJNI
* Method: Test
* Signature: (Ljava/lang/Character;Ljava/lang/Double;)Ljava/lang/Long;
*/
JNIEXPORT jobject JNICALL Java_com_example_wastrel_hellojni_HelloJNI_Test
(JNIEnv *, jclass, jobject, jobject);
通過以上程式碼可以可以看出,過載的方法生成的標頭檔案後函式名後面都追加引數的型別簽名,並且‘/’被替換成了下劃線‘_’,‘;’被替換成了數字‘2’;‘[’被替換成了數字‘3’。在簽名中()裡面表示方法的引數,緊接著的是返回型別對應的簽名。可以看到String getFromCString
因為沒有引數,所以()裡面什麼都沒有,但其有一個返回引數String,String並不是Java的基礎型別,String的全稱是java.lang.String
,根據簽名規則就是Ljava/lang/String;
,因此該方法的簽名是()Ljava/lang/String
。這裡需要注意,如果一個Java函式沒有返回即void,那麼對應的返回型別簽名就是V。
其餘函式有興趣可以根據上述規則推理,我相信各位程式設計師的推理能力,這裡就不一一講解。
後記
方法簽名是為了便於Java與native程式碼的相互訪問,後面通過C++呼叫Java程式碼的時候,方法簽名尤為重要。在傳遞複雜型別的時候相對較為麻煩,在實際使用中並不建議傳遞複雜物件。這裡說一下Java方法過載,在編寫native函式的時候不建議使用過載,過載的方法名稱很長,辨識度也不高。更建議在java中預處理過載的呼叫。例如:
public class NativeFunc{
public String Func(String str){
return native_func1(str);
}
public String Func(int i){
return native_func2(i);
}
public native String native_func1(String str);
public native String native_func2(int i);
}
相關文章
- Android Studio NDK 入門教程(2)--Java與C++之間的簡單資料轉換與傳遞AndroidJavaC++
- Mac之Android Studio開發NDK入門MacAndroid
- Android Studio NDK 入門教程(1)--來自C 語言的StringAndroid
- Android NDK開發中java資料型別與C/C++資料型別的對應關係AndroidJava資料型別C++
- Android NDK入門:C++ 基礎知識AndroidC++
- Java入門教程十二(集合與泛型)Java泛型
- NDK 知識梳理(3) JNI 之 Java 和 JNI 資料型別對映Java資料型別
- Android -- NDK開發入門Android
- PHP入門之型別與運算子(一)PHP型別
- C++入門教程(5):基本資料型別和變數C++資料型別變數
- JNI/NDK開發指南(3):JNI資料型別及與Java資料型別的對映關係資料型別Java
- Android Studio ndk-Jni開發詳細入門,Aes加密demoAndroid加密
- MySql與Java的時間型別MySqlJava型別
- Android Studio教程從入門到精通2.0Android
- 蘋果企業簽名與其他簽名區別與好處蘋果
- Android之重新簽名APKAndroidAPK
- Android Studio 簽名打包過程圖解Android圖解
- Android Studio NDK開發-JNI呼叫Java方法AndroidJava
- Android Studio NDK:二、JNI 返回JAVA 實體AndroidJava
- Android Studio3.0 NDK配置與開發Android
- Android Studio 從入門到精通視訊教程Android
- 電子簽名與手寫簽名的區別,電子簽名的優勢是什麼?
- C#名稱空間、型別的別名管理C#型別
- 檢視keystore別名和android簽名Android
- Android Studio 使用正式簽名進行除錯Android除錯
- Android Studio NDK開發:JNI呼叫Java函式AndroidJava函式
- Android Studio NDK :一、基礎入門(基於gradle-experimental外掛)AndroidGradle
- NodeJS 和 C++ 之間的型別轉換NodeJSC++型別
- 蘋果企業簽名的三種型別,企業簽名是如何分類的?蘋果型別
- C++入門教程C++
- eclipse,android studio 簽名打包,獲取MD5, SHA1(應用的簽名)EclipseAndroid
- Java 資料型別之間的轉換Java資料型別
- Android Studio生成簽名檔案,自動簽名,以及獲取SHA1和Android
- 【Android Studio】入門系列 3.建或匯入APPAndroidAPP
- Redis入門教程(二)— 基本資料型別Redis資料型別
- Android Studio 入門指南Android
- C++入門教程(3):語句和縮排C++
- android studio配置ndk開發Android