日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android JNI和NDK学习(5)--JNI分析API

發布時間:2023/12/10 Android 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android JNI和NDK学习(5)--JNI分析API 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java類型和本地類型對應

在如下情況下,需要在本地方法中應用java對象的引用,就會用到類型之間的轉換:

  • java方法里面將參數傳入本地方法;
  • 在本地方法里面創建java對象;
  • 在本地方法里面return結果給java程序。
  • Java基本類型

    像booleans、integers、floats等從Java程序中傳到本地方法中的原始類型可以直接使用,下面是java中的原始類型和本地方法中的類型的對應:

    Java 類型本地類型說明

    boolean jboolean 無符號,8 位 byte jbyte 無符號,8 位 char jchar 無符號,16 位 short jshort 有符號,16 位 int jint 有符號,32 位 long jlong 有符號,64 位 float jfloat 32 位 double jdouble 64 位 void void N/A

    也就是說如果我在方法中傳進去了一個boolean的參數的話,那么我在本地方法中就有jboolean類型與之對應。同理,如果在本地方法中return一個jint的話,那么在java中就返回一個int類型。

    為了使用方便,特提供以下定義。

    #define JNI_FALSE 0 #define JNI_TRUE 1

    jsize 整數類型用于描述主要指數和大小:
    typedef jint jsize;

    Java String類型

    在java中,使用的字符串String對象是Unicode碼,即每個字符不論是中文還是英文或是符號,一個字符總是占用兩個字節。
    在c/c++本地代碼中創建java的String對象
    .java通過JNI接口可以將java的字符串轉換到c/c++中的寬字符串(wchar_t ),或是傳回一個UTF-8的字符串(char )到c/c++。反過來,c/c++可以通過一個寬字符串,或是一個UTF-8編碼的字符串來創建一個java端的String對象。

    GetStringChars/GetStringUTFChars

    .這兩個函數用來取得與某個jstring對象相關的java字符串。分別可以取得UTF-16編碼的寬字符串(jchar)跟UTF-8編碼的字符串(char)。

    Const jchar* GetStringChars(jstring str, jboolean* copied) Const char* GetStringUTFChars(jstring str, jboolean* copied)

    第一個參數傳入一個指向java中的String對象的jstring變量
    第二個參數傳入的是一個jboolean的指針。
    這兩個函數分別都會有兩個不同的動作:
    第一個參數:

  • 開新內存,然后把java中的String拷貝到這個內存中,然后返回這個內存地址的指針。
  • 直接返回指向java中string的內存的指針,這個時候千萬不要改變這個內存的內容,這將破壞String在java中始終是常量這個原則。
    第二個參數:
    是用來標示是否對java的string對象進行了拷貝的。
    如果傳入的這個jboolean指針不是null,則他會給該指針指向的內存傳入JNI_TRUE或JNI_FALSE標示是否進行了拷貝。
    傳入null標示不關心是否拷貝字符串,它就不會給jboolean*指向的內存賦值。
    使用這兩個函數取得的字符串,在不使用的時候,要使用ReleaseStringChars/ReleaseStringUTFChars來釋放拷貝的內存,或是釋放對java的String對象的引用。

    ReleaseStringChars(jstring jstr, const jchar* str);
    ReleaseStringUTFChars(jstring jstr, const char* str);

  • 第一個參數指定一個jstring變量,即是要釋放的本地字符串的來源。
    第二個參數就是要釋放的本地字符串

    訪問類對象的屬性

    env 為 JNIEnv,obj的類型為jobject

    JAVA_FieldAccessTest_accessField(JNIEnv *env,jobject obj){jfieldID fid;jclass cls = (*env)->GetObjectClass(env, obj);//類FieldAccessTest中有個String類型的屬性s//獲取要訪問的屬性的idfid = (*env)->GetFieldID(evn,cls,"s","Ljava/lang/String;");//讀取屬性值jstring jstr = (*env)->GetObjectField(env,obj,fid);char* str = (*evn)->GetStringUTFChars(env,jstr,NULL);//釋放資源 (*env)->ReleaseStringUTFChars(env,jstr,str);//現在反過來,改變調用該本地方法的java對象的屬性值jstr = (*env)->NewStringUTF(env,"88888");(*env)->SetObjectField(env,obj,fid,jstr);}

    總結:

    1. jfieldID fid = (*env)->GetFieldID(env,對象所屬的類的jclass,屬性名,屬性對應的屬性描述符號); 2. (*env)->GetObjectField(env,對象,屬性id);

    訪問靜態屬性:

    假如有個類如下:

    class StaticFielcTest {private static int si;private native void accessField(); }

    那么實現為:

    JNIEXPORT void JNICALL Java_StaticFieldTest_accessField(JNIEnv *env, jobject obj) {jfieldID fid; /* store the field ID */jint si;jclass cls = (*env)->GetObjectClass(env, obj); //獲取類classfid = (*env)->GetStaticFieldID(env, cls, "si", "I"); //獲取靜態屬性idsi = (*env)->GetStaticIntField(env, cls, fid); //讀去屬性的值(*env)->SetStaticIntField(env, cls, fid, 200); //設置靜態屬性的值 }

    訪問實例方法

    假如有個這樣的類:

    class MethodCall {private native void nativeMethod();private void callback() {System.out.println("In Java CallBack");}public static void main(String args[]) {MethodCall c = new MethodCall();c.nativeMethod(); } static {System.loadLibrary("InstanceMethodCall");} }

    jni實現:

    JNIEXPORT void JNICALL Java_MethodCall_nativeMethod(JNIEnv *env, jobject obj) {//1.拿到classjclass cls = (*env)->GetObjectClass(env, obj); //2.拿到方法idjmethodID mid = (*env)->GetMethodID(env, cls, "callback", "()V"); //3.根據obj,和方法id 調用方法(*env)->CallVoidMethod(env, obj, mid); }

    根據方法的返回值來決定調用哪個方法:

    如果返回int 那么最后一步就調用 (*env)->CallIntMethod(env,obj,mid);

    最后那個參數 "()V" 是方法描述符:

    (I)V 帶一個int 類型的參數,返回值類型為void
    ()D 沒有參數,返回double //注意!!沒有參數并不是 (V)D

    方法public static void main(String[] args) 對應的方法描的符為:

    ([Ljava/lang/String;)V

    訪問靜態方法

    jclass cls = (*env)->GetObjectClass(env, obj); jmethodID mid =(*env)->GetStaticMethodID(env, cls, "callback", "()V"); (*env)->CallStaticVoidMethod(env, cls, mid); //注意,這里跟訪問實例方法的區別是 第二個參數不是obj,而是cls

    轉載于:https://www.cnblogs.com/CommonQ/p/4062392.html

    總結

    以上是生活随笔為你收集整理的Android JNI和NDK学习(5)--JNI分析API的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。