<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          JNI:操作字符串String

          共 3510字,需瀏覽 8分鐘

           ·

          2022-03-04 01:00

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

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

          • 使用函數(shù) NewObject 可以用來(lái)創(chuàng)建Java對(duì)象

          • GetMethod 能夠取得構(gòu)造方法的 jmethodID,如果傳入的要取的方法名稱(chēng)設(shè)定為 "" 就能夠取得構(gòu)造方法

          • 因?yàn)闃?gòu)造方法沒(méi)有返回值,所以構(gòu)造方法的方法返回值類(lèi)型的簽名始終為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對(duì)象的創(chuàng)建 AllocObject

          • 使用函數(shù) AllocObject 可以根據(jù)傳入的 jclass 創(chuàng)建一個(gè) Java 對(duì)象,但是他的狀態(tài)是非初始化的,在使用這個(gè)對(duì)象之前一定要調(diào)用 CallNonvirtualVoidMethod 來(lái)調(diào)用該 jclass 的構(gòu)造函數(shù),這樣就可以延遲構(gòu)造函數(shù)的調(diào)用。這一個(gè)部分用的很少,在這里只做簡(jiǎn)單的說(shuō)明。

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

          jclass clazz_this = env->GetObjectClass( obj );//這里假設(shè)這個(gè)對(duì)象的類(lèi)中有定義 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++本地代碼中訪(fǎng)問(wèn)Java的String字符串對(duì)象

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

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

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

          2.1 ?GetStringChars & GetStringUTFChars

          GetStringCharsGetStringUTFChars
          • 這兩個(gè)函數(shù)用來(lái)取得某個(gè)jstring對(duì)象相關(guān)的Java字符串。分別可以取得UTF-16編碼的寬字符串(jchar*)與UTF8編碼的字符串(char*)

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

          第一個(gè)參數(shù)傳入一個(gè)指向 Java 中的 String 字符串對(duì)象的 jstring 變量;

          第二參數(shù)傳入的是一個(gè)jboolean的指針;

          • 這兩個(gè)函數(shù)分別都會(huì)有兩個(gè)不同的動(dòng)作:

          1. 開(kāi)辟新內(nèi)存,然后把Java中的String拷貝到這個(gè)內(nèi)存中,然后返回指向這個(gè)內(nèi)存地址的指針

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

          • 第二個(gè)參數(shù)是用來(lái)標(biāo)識(shí)是否對(duì)Java的String對(duì)象進(jìn)行了拷貝的

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

          傳入NULL表示不關(guān)心是否拷貝字符串,它就不會(huì)給jboolean*指向的內(nèi)存賦值

          • 使用這兩個(gè)函數(shù)取得的字符串,在不使用的時(shí)候,必須使用ReleaseStringChars / ReleaseStringUTFChars 來(lái)釋放拷貝的內(nèi)存,或者是否對(duì)Java的String對(duì)象的應(yīng)用。

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

          第一個(gè)參數(shù)指定一個(gè) jstring 變量,即是要釋放的本地字符串的來(lái)源;

          第二個(gè)參數(shù)就是要釋放的本地字符串;

          2.2 GetStringCritical

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

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

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

          • 雖說(shuō)這個(gè)函數(shù)會(huì)增加直接傳回指向Java字符串的指針的可能性,不過(guò)還是會(huì)根據(jù)情況傳回拷貝過(guò)的字符串

          • 不支持GetStringUTFCritical,沒(méi)有這樣的函數(shù)。由于Java字符串用的是UTF16編碼,要轉(zhuǎn)換成UTF8編碼的字符串始終需要進(jìn)行一次拷貝,所以沒(méi)有這樣的函數(shù)。

          2.3 GetStringRegin & GetStringUTFRegion

          • Java 1.2 增加了 GetStringRegin / GetStringUTFRegion 函數(shù)。這個(gè)函數(shù)的動(dòng)作,是把Java字符串的內(nèi)容直接拷貝到 C/C++ 的字符數(shù)組中。在調(diào)用這個(gè)函數(shù)之前必須有一個(gè) C/C++ 分配出來(lái)的字符串,然后傳入到這個(gè)函數(shù)中進(jìn)行字符串的拷貝

          • 由于 C/C++ 中分配內(nèi)存開(kāi)銷(xiāo)相對(duì)小,而且Java中的String內(nèi)容拷貝的開(kāi)銷(xiāo)可以忽略,更好的一點(diǎn)是此函數(shù)不分配內(nèi)存,不會(huì)拋出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 其他字符串函數(shù)

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

          分享&在看

          瀏覽 56
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产一级a毛一级a看免费视频野外 | 黄片大全在线免费观看 | 婷婷丁香社区 | 草草视频在线观看 | 永久免费看黄色视频 |