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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

【Android NDK 开发】JNI 方法解析 ( 字符串数组参数传递 | 字符串遍历 | 类型强转 | Java 字符串与 C 字符串转换 | 字符串释放 )

發(fā)布時(shí)間:2025/6/17 Android 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Android NDK 开发】JNI 方法解析 ( 字符串数组参数传递 | 字符串遍历 | 类型强转 | Java 字符串与 C 字符串转换 | 字符串释放 ) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

        • I . C/C++ 中的 Java 字符串?dāng)?shù)組類型
        • II . 獲取字符串?dāng)?shù)組長度
        • III . 獲取字符串?dāng)?shù)組元素
        • IV . 類型強(qiáng)轉(zhuǎn) ( jobject -> jstring )
        • V . 字符串轉(zhuǎn)換 ( jstring -> char* )
        • VI . 字符串釋放
        • VII . 部分代碼示例



I . C/C++ 中的 Java 字符串?dāng)?shù)組類型



JNI 中 C/C++ 代碼里的 Java 字符串?dāng)?shù)組類型 : jobjectArray ;

① JNI 類型現(xiàn)狀 : 在 JNI 中沒有定義 Java 字符串?dāng)?shù)組類型 , 只定義了 Java 字符串類型 jstring ;

② Object 對(duì)應(yīng) jobject : 在 C/C++ 環(huán)境中 jobject 類型對(duì)應(yīng) Java 中的 Object 類型 , Java 中字符串也是 Object 類型的 ;

③ 字符串?dāng)?shù)組類型 : 因此在 C/C++ 環(huán)境中使用 對(duì)象數(shù)組 jobjectArray 來當(dāng)做 字符串?dāng)?shù)組類型 ;



II . 獲取字符串?dāng)?shù)組長度



1 . 前提條件 : Java 層傳入?yún)?shù) jobjectArray stringArray , 該參數(shù)對(duì)應(yīng) Java 代碼中的 String[] stringArray 參數(shù) ;

下面的 GetArrayLength 方法的 stringArray 參數(shù) , 就是 jobjectArray 類型的 ;


2 . 獲取字符串?dāng)?shù)組長度 代碼示例 : 其中返回值 jsize 是 int 類型的別名 ;

jsize stringArrayLength = env->GetArrayLength(stringArray);

GetArrayLength 方法詳細(xì)解析參考如下內(nèi)容 :
GetArrayLength 方法解析 ( 獲取 jarray 數(shù)組長度 )



III . 獲取字符串?dāng)?shù)組元素



C/C++ 代碼中獲取指定索引的 Java 字符串?dāng)?shù)組類型的元素 ;


1 . 調(diào)用方法 : 調(diào)用 JNIEnv * env 的 GetObjectArrayElement 方法 , 可以獲取指定索引的 jobject 引用類型變量 ;


2 . 方法原型 :

struct _JNIEnv {/* _JNIEnv 結(jié)構(gòu)體中封裝了 JNINativeInterface 結(jié)構(gòu)體指針 */const struct JNINativeInterface* functions;...// 最終 調(diào)用的 還是 JNINativeInterface 結(jié)構(gòu)體中封裝的 GetObjectArrayElement方法jobject GetObjectArrayElement(jobjectArray array, jsize index){ return functions->GetObjectArrayElement(this, array, index); }... }

3 . GetObjectArrayElement 參數(shù)說明 :

① jobjectArray array 參數(shù) : 由 Java 層傳入的 Java 對(duì)象數(shù)組 ;

② jsize index 參數(shù) : 要獲取的數(shù)組元素的索引值 ;


4 . 獲取對(duì)象數(shù)組指定元素代碼示例 :

其中的參數(shù) stringArray 是 jobjectArray 類型的 , 由 JNI 方法傳入 ;

其中的參數(shù) i 是 int 類型的 , 是要獲取的元素的索引值 , 從 0 開始計(jì)數(shù) ;

jobject string_object = env->GetObjectArrayElement(stringArray, i);

IV . 類型強(qiáng)轉(zhuǎn) ( jobject -> jstring )



將 jobject 轉(zhuǎn)為 jstring 類型 : string_object 是 jobject 類型變量 ;

// 2.2 將 jobject 類型強(qiáng)轉(zhuǎn)成 jstring 類型 , 這兩個(gè)都代表了 Java 的數(shù)據(jù)類型jstring string_java = static_cast<jstring>(string_object);

詳細(xì)內(nèi)容參考下面博客 :
【C++ 語言】類型轉(zhuǎn)換 ( 轉(zhuǎn)換操作符 | const_cast | static_cast | dynamic_cast | reinterpret_cast | 字符串轉(zhuǎn)換 )



V . 字符串轉(zhuǎn)換 ( jstring -> char* )



1 . GetStringUTFChars 方法 : 將 jstring 類型字符串 ( Java 中的字符串 ) 轉(zhuǎn)為 char* 類型字符串 ( C/C++ 中的字符串 ) ;


2 . 函數(shù)原型 : jstring string 參數(shù)是 Java 通過 JNI 傳入的 , 代表 Java 字符串 ;

struct _JNIEnv {/* _JNIEnv 結(jié)構(gòu)體中封裝了 JNINativeInterface 結(jié)構(gòu)體指針 */const struct JNINativeInterface* functions;...// 最終 調(diào)用的 還是 JNINativeInterface 結(jié)構(gòu)體中封裝的 GetStringUTFChars 方法const char* GetStringUTFChars(jstring string, jboolean* isCopy){ return functions->GetStringUTFChars(this, string, isCopy); }... }

3 . jboolean* isCopy 參數(shù) : 該參數(shù)用于指定將 jintArray 類型的變量 , 轉(zhuǎn)為 jint * 指針類型的變量 , 新的指針變量的生成方式 ;


① 將 該參數(shù)設(shè)置成指向 JNI_TRUE 的指針 : 將 int 數(shù)組數(shù)據(jù)拷貝到一個(gè)新的內(nèi)存空間中 , 并將該內(nèi)存空間首地址返回 ;

② 將 該參數(shù)設(shè)置成指向 JNI_FALSE 的指針 : 直接使用 java 中的 int 數(shù)組地址 , 返回 java 中的 int 數(shù)組的首地址 ;

③ 將 該參數(shù)設(shè)置成 NULL ( 推薦 ) : 表示不關(guān)心如何實(shí)現(xiàn) , 讓系統(tǒng)自動(dòng)選擇指針生成方式 , 一般情況下都不關(guān)心該生成方式 ;

④ jboolean 類型取值 : jboolean 的取值只能是 0 和 1 , 也可以使用 JNI_FALSE 和 JNI_TRUE 宏定義 ;

#define JNI_FALSE 0 #define JNI_TRUE 1

4 . jstring 字符串轉(zhuǎn)換 為 char* 字符串示例 :

const char *string_c = env->GetStringUTFChars(string_java, JNI_FALSE);

VI . 字符串釋放



1 . ReleaseStringUTFChars 方法 : 將 Java 字符串 和 C/C++ 字符串都釋放 ;


2 . 函數(shù)原型 :

jstring string 參數(shù)是 Java 通過 JNI 傳入的 , 代表 Java 字符串 ;

const char* utf 參數(shù)是通過 GetStringUTFChars 方法將上面的 Java 字符串轉(zhuǎn)成的 C/C++ 字符串 ;

struct _JNIEnv {/* _JNIEnv 結(jié)構(gòu)體中封裝了 JNINativeInterface 結(jié)構(gòu)體指針 */const struct JNINativeInterface* functions;...// 最終 調(diào)用的 還是 JNINativeInterface 結(jié)構(gòu)體中封裝的 ReleaseStringUTFChars 方法void ReleaseStringUTFChars(jstring string, const char* utf){ functions->ReleaseStringUTFChars(this, string, utf); }... }


VII . 部分代碼示例



部分代碼示例 :

#include <jni.h> #include <string>//導(dǎo)入日志庫 #include <android/log.h>//定義日志宏 , 其中的 __VA_ARGS__ 表示可變參數(shù) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,"JNI",__VA_ARGS__);...extern "C" JNIEXPORT void JNICALL Java_kim_hsl_jni_MainActivity_jniArrayTest(JNIEnv *env, jobject instance, jintArray intArray_,jobjectArray stringArray) {...// II . 引用類型數(shù)組操作 ( 獲取字符串?dāng)?shù)組 )// 1 . 獲取字符串?dāng)?shù)組長度jsize stringArrayLength = env->GetArrayLength(stringArray);// 2 . 遍歷字符串?dāng)?shù)組for(int i = 0; i < stringArrayLength; i ++) {/*2.1 獲取 jobject 數(shù)組中第 i 個(gè)元素注意 : 獲取的是 jobject 類型變量函數(shù)原型 : jobject GetObjectArrayElement(jobjectArray array, jsize index)jobjectArray array 參數(shù) : 是 Java 層傳入的 Java 對(duì)象數(shù)組 參數(shù) , 即 Native 層的調(diào)用函數(shù)的參數(shù)jsize index 參數(shù) : 對(duì)象元素的索引值 , 取值范圍 0 ~ stringArrayLength - 1返回值 : 返回的是 jobject 類型的變量*/jobject string_object = env->GetObjectArrayElement(stringArray, i);// 2.2 將 jobject 類型強(qiáng)轉(zhuǎn)成 jstring 類型 , 這兩個(gè)都代表了 Java 的數(shù)據(jù)類型jstring string_java = static_cast<jstring>(string_object);/*2.3 將 jstring 類型轉(zhuǎn)為 char* 類型jstring 類型簡介 :class _jobject {};class _jstring : public _jobject {};typedef _jstring* jstring;由上面可見 , jstring 只是 繼承了 _jobject 類 , 沒有任何實(shí)現(xiàn) , 是一個(gè)空類因此需要借助 C/C++ 方法 將 java 類型的 jstring 字符串 其轉(zhuǎn)為 C/C++ 類型的 char* 類型字符串轉(zhuǎn)換函數(shù)原型 : void ReleaseStringUTFChars(jstring string, const char* utf)*/const char *string_c = env->GetStringUTFChars(string_java, 0);// 2.4 打印 轉(zhuǎn)換后的 字符串值__android_log_print(ANDROID_LOG_INFO, "JNI_TAG", "打印字符串?dāng)?shù)組元素 : %d . %s", i, string_c);// 2.5 釋放 char* 字符串env->ReleaseStringUTFChars(string_java, string_c);}}

代碼執(zhí)行結(jié)果 :

01-12 19:45:59.634 11885-11885/kim.hsl.jni I/JNI_TAG: 打印 int 數(shù)組元素 : 0 . 1 01-12 19:45:59.634 11885-11885/kim.hsl.jni I/JNI_TAG: 打印 int 數(shù)組元素 : 1 . 2 01-12 19:45:59.634 11885-11885/kim.hsl.jni I/JNI_TAG: 打印 int 數(shù)組元素 : 2 . 666 01-12 19:45:59.634 11885-11885/kim.hsl.jni I/JNI_TAG: 打印 int 數(shù)組元素 : 3 . 888 01-12 19:45:59.634 11885-11885/kim.hsl.jni I/JNI_TAG: 打印 int 數(shù)組元素 : 4 . 95555 01-12 19:45:59.634 11885-11885/kim.hsl.jni I/JNI_TAG: 打印字符串?dāng)?shù)組元素 : 0 . Hello 01-12 19:45:59.634 11885-11885/kim.hsl.jni I/JNI_TAG: 打印字符串?dāng)?shù)組元素 : 1 . World 01-12 19:45:59.634 11885-11885/kim.hsl.jni I/JNI_TAG: 打印字符串?dāng)?shù)組元素 : 2 . Hanshuliang 01-12 19:45:59.634 11885-11885/kim.hsl.jni I/JNI_TAG: Java 層 jniArrayTest 執(zhí)行完畢后 , int[] intArray 數(shù)組內(nèi)容 : [8888, 8888, 8888, 8888, 8888]

限于篇幅就不再貼完整代碼了 , 去下載博客資源有全套的 JNI 文檔教程 , 及博客源碼

總結(jié)

以上是生活随笔為你收集整理的【Android NDK 开发】JNI 方法解析 ( 字符串数组参数传递 | 字符串遍历 | 类型强转 | Java 字符串与 C 字符串转换 | 字符串释放 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。