JNI系列入門之Hello JNI C(二)

JNI系列文章:
JNI系列之入門Hello JNI C(一)
JNI系列之入門Hello JNI C(二)
JNI系列入門之C語言與Java的雙向通信(一)
JNI系列入門之C語言與Java的雙向通信(二)
JNI系列入門之C語言中文字符串亂碼問題


即上一篇JNI系列之入門Hello JNI C(一)簡單介紹后,這篇將詳細講解C中的所有代碼。


  • 理解C中native函數(shù)實現(xiàn)的意思
    我們來看生成出來的native函數(shù)聲明
/*
 * Class:     com_jerry_jnitest_JniTest
 * Method:    getStringFromC
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_jerry_jnitest_JniTest_getStringFromC
  (JNIEnv *, jclass);
  1. Java_com_jerry_jnitest_JniTest_getStringFromC這一長串是函數(shù)名,它是有規(guī)律的:
    Java_native方法在java類中的包名全稱_native的方法名
    原來java里native方法:
public native static String getStringFromC();
  1. 再來看返回值 jstring,對應的是java中native方法的返回值String,通過VS右擊它轉(zhuǎn)到定義,會發(fā)現(xiàn)它就是一個_jobject結構體指針變量jobject的別名:


    Paste_Image.png
  2. 參數(shù)JNIEnv *,它在java的native方法里沒有對應的參數(shù),這個是JNI接口函數(shù)特有的,包括后面的jclass或者jobject是必須有的兩個參數(shù)。
    JNIEnv *是個啥玩意呢,通過VS轉(zhuǎn)到定義:


    Paste_Image.png

    有兩個地方都聲明了:
    一個是C++的,一個是C的。
    C中是結構體指針struct JNINativeInterface_ *的一個別名,那就說明JNIEnv *就是一個二級指針類型。
    C++中:


    Paste_Image.png

    圖中可以看到JNIEnv是JNIEnv_的一個別名,而JNIEnv_是個結構體,里面JNINativeInterface_ *function作為它的一個成員變量,圖中可以看到C++對function的函數(shù)封裝了一層,參數(shù)傳了this,也就是當前functions這個結構體指針其實就是上文C中JNIEnv這個JNINativeInterface_ *結構體指針的別名。那意思就很明白了,在c++中native函數(shù)的JNIEnv *就是一級指針。
    至于C中為什么要用二級指針,應該是結構體中的那些函數(shù)指針的具體實現(xiàn)都需要用到JNINativeInterface_ *這個結構體指針吧。(這段話比較拗口,會比較難理解,可以多看看思考思考)
    native函數(shù)中,第二個參數(shù)jclass,看看它的定義:
    Paste_Image.png

    其實它的意思就是相對于java的Class類型,因為我們在Java中寫的native方法是 static修飾的所以直接是類類型來訪問應用這個native方法。
    如果java中改成:

public native String getStringOfC(String input);

那就變成了:

JNIEXPORT jstring JNICALL Java_com_jerry_jnitest_JniTest_getStringOfC
  (JNIEnv *env, jobject jobj, jstring jstr){

    }

這里面jobject標示這個native方法是調(diào)用它的對象,第三個參數(shù)jstring就是java方法中String input這個參數(shù)。
從上文可以看出,jxxxx的都會對應Java中的一種數(shù)據(jù)類型。

下面是Java的數(shù)據(jù)類型與JNI的數(shù)據(jù)類型的映射關系:

Java數(shù)據(jù)類型 Jni數(shù)據(jù)類型 C數(shù)據(jù)類型
基礎數(shù)據(jù)類型
void void void
boolean jboolean unsigned char
byte jbyte signed char
char jchar char
short jshort short
int jint int
long jlong __int64(long long)
float jfloat float
double jdouble double
引用數(shù)據(jù)類型
String jstring (jobject的別名) struct _jobject*
Object jobject struct _jobject*
基本數(shù)據(jù)類型的數(shù)組
blooean[] jbooleanArray
1. jbooleanArray是jarray的別名
2. jarray又是jobject的別名
struct _jobject *
byte[] jbyteArray
1. jbyteArray是jarray的別名
2. jarray又是jobject的別名
struct _jobject *
char[] jcharArray
1. jcharArray是jarray的別名
2. jarray又是jobject的別名
struct _jobject *
short[] jshortArray
1. jshortArray是jarray的別名
2. jarray又是jobject的別名
struct _jobject *
int[] jintArray
1. jintArray是jarray的別名
2. jarray又是jobject的別名
struct _jobject *
long[] jlongArray
1. jlongArray是jarray的別名
2. jarray又是jobject的別名
struct _jobject *
float[] jfloatArray
1. jfloatArray是jarray的別名
2. jarray又是jobject的別名
struct _jobject *
double[] jdoubleArray
1. jdoubleArray是jarray的別名
2. jarray又是jobject的別名
struct _jobject *
引用數(shù)據(jù)類型數(shù)組
Object[] jobjectArray
1. jobjectArray是jarray的別名
2. jarray又是jobject的別名
struct _jobject *

JNI系列文章:
JNI系列之入門Hello JNI C(一)
JNI系列之入門Hello JNI C(二)
JNI系列入門之C語言與Java的雙向通信(一)
JNI系列入門之C語言與Java的雙向通信(二)
JNI系列入門之C語言中文字符串亂碼問題

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容