1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        JNI:操作字符串String

        共 3510字,需瀏覽 8分鐘

         ·

        2022-03-04 01:00

        1. 在C/C++本地代碼中創(chuàng)建Java的對象

        1.1 Java對象的創(chuàng)建使用 NewObject 方法

        • 使用函數 NewObject 可以用來創(chuàng)建Java對象

        • GetMethod 能夠取得構造方法的 jmethodID,如果傳入的要取的方法名稱設定為 "" 就能夠取得構造方法

        • 因為構造方法沒有返回值,所以構造方法的方法返回值類型的簽名始終為void

        案例

        jclass class_date = env->FindClass("java/util/Date");jmethodID mid_date = env->GetMethodId(class_date, "", "()V");jobject now = env->NewObject(class_date, mid_date);
        jmethodID mid_date_getTime = env->GetMethod(class_date , "getTime", "()j");jlong time = CallLongMethod(now, mid_date_getTime);
        cout << time << endl;

        1.2 Java對象的創(chuàng)建 AllocObject

        • 使用函數 AllocObject 可以根據傳入的 jclass 創(chuàng)建一個 Java 對象,但是他的狀態(tài)是非初始化的,在使用這個對象之前一定要調用 CallNonvirtualVoidMethod 來調用該 jclass 的構造函數,這樣就可以延遲構造函數的調用。這一個部分用的很少,在這里只做簡單的說明。

        jclass clazz_str = env->FindClass("java/lang.String");jmethodID methodID_str = env->GetMethodID(clazz_str, "", "([C)V");
        //預先創(chuàng)建一個沒有初始化的字符串jobject str = env->AllocObject(clazz_str);//創(chuàng)建一個4個元素的字符串數組,然后以 'B' 'U' 'G' '弄' '潮' '兒' 賦值jcharArray arg = env->NewCharArray(6);env->SetCharArrayRegion(arg, 0, 6, L"BUG弄潮兒");//調用構造函數env->CallNonvirtualVoidMethod(str, clazz_str, methodID_str, arg);

        jclass clazz_this = env->GetObjectClass( obj );//這里假設這個對象的類中有定義 static String STATIC_STR;jfieldID jfield_str = env->GetStaticField( clazz_this, "STATIC_STR", "Ljava/lang/String;");env->SetStaticObjectField(clazz_str, jfield_str, str);

        2. Java字符串 & C/C++的字符串

        在C/C++本地代碼中訪問Java的String字符串對象

        在C/C++本地代碼中創(chuàng)建Java的String字符串對象

        • 在Java中,使用的字符串String對象是 Unicode ( UTF-16 ) 編碼,即每個字符不論是中文、英文還是符號,一個字符總是占兩個字節(jié)

        • Java 通過 JNI 接口可以將 Java的字符串轉換到 C/C++ 中的寬字符串(wchar_t*),或者是傳回一個UTF-8的字符串(char*)到 C/C++。反過來,C/C++ 可以通過一個寬字符串,或者是一個 UTF-8 編碼的字符串來創(chuàng)建一個Java端的 String 對象

        2.1 ?GetStringChars & GetStringUTFChars

        GetStringCharsGetStringUTFChars
        • 這兩個函數用來取得某個jstring對象相關的Java字符串。分別可以取得UTF-16編碼的寬字符串(jchar*)與UTF8編碼的字符串(char*)

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

        第一個參數傳入一個指向 Java 中的 String 字符串對象的 jstring 變量;

        第二參數傳入的是一個jboolean的指針;

        • 這兩個函數分別都會有兩個不同的動作:

        1. 開辟新內存,然后把Java中的String拷貝到這個內存中,然后返回指向這個內存地址的指針

        2. 直接返回指向 Java 中 String 內存的指針。這個時候千萬不要改變這個內存的內容;如果改變,那么這樣將破壞String在Java中始終是常量這個原則

        • 第二個參數是用來標識是否對Java的String對象進行了拷貝的

        如果傳入的這個jboolean指針不是NULL,則它會給該指針指向的內存?zhèn)魅隞NI_TRUE或者JNI_FALSE表示是否進行了拷貝

        傳入NULL表示不關心是否拷貝字符串,它就不會給jboolean*指向的內存賦值

        • 使用這兩個函數取得的字符串,在不使用的時候,必須使用ReleaseStringChars / ReleaseStringUTFChars 來釋放拷貝的內存,或者是否對Java的String對象的應用。

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

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

        第二個參數就是要釋放的本地字符串;

        2.2 GetStringCritical

        • 為了增加直接傳入指向Java字符串的指針的可能性(而不是拷貝),JDK 1.2 增加了函數 GetStringCritical / ReleaseStringCritical

        const jchar* GetStringCritical( jstring str, jboolean* copied);void ReleaseStringCritical( jstring jstr, const jchar* str);
        • 在GetStringCritical /ReleaseStringCritical 之間是一個關鍵區(qū),在這個關鍵區(qū)之間絕對不能呼叫 JNI 的其他函數和會造成當前線程中斷或是會讓當前線程等待的任何本地代碼。否則將造成關鍵區(qū)代碼執(zhí)行期間垃圾回收器停止運作,任何觸發(fā)垃圾回收器的線程也會暫停。其它的觸發(fā)垃圾回收器的線程不能前進直到當前線程結束而激活垃圾回收器

        • 在關鍵區(qū)中千萬不要出現中斷操作,或是在JVM中分配任何新對象;否則會造成JVM死鎖

        • 雖說這個函數會增加直接傳回指向Java字符串的指針的可能性,不過還是會根據情況傳回拷貝過的字符串

        • 不支持GetStringUTFCritical,沒有這樣的函數。由于Java字符串用的是UTF16編碼,要轉換成UTF8編碼的字符串始終需要進行一次拷貝,所以沒有這樣的函數。

        2.3 GetStringRegin & GetStringUTFRegion

        • Java 1.2 增加了 GetStringRegin / GetStringUTFRegion 函數。這個函數的動作,是把Java字符串的內容直接拷貝到 C/C++ 的字符數組中。在調用這個函數之前必須有一個 C/C++ 分配出來的字符串,然后傳入到這個函數中進行字符串的拷貝

        • 由于 C/C++ 中分配內存開銷相對小,而且Java中的String內容拷貝的開銷可以忽略,更好的一點是此函數不分配內存,不會拋出OutOfMemoryError 異常

        //拷貝Java字符串并以UTF-8編碼傳入bufferGetStringUTFRegion( jstring srt, jsize start, jsize len, char* buffer);
        //拷貝Java字符串并以UTF-16編碼傳入bufferGetStringRegion( jstring srt, jsize start, jsize len, char* buffer);


        2.4 其他字符串函數

        jstring NewString( const jchar* str, jsize len);
        jstring NewStringUTF(const char* str);
        jsize GetStringLength(jstring str);
        jsize GetStringUTFLength(jstring str);

        分享&在看

        瀏覽 56
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            草我骚逼 | 嗯嗯嗯啊啊啊视频 | 99东京热| 丁香婷婷激情 | 亚洲变态另类 | 亚洲AV无码成人精品一区色欲 | 夜夜高潮夜夜爽 | 天天天天色天天天干 | 亚洲色图导航 | 天天插日日操 |