AndroidのNDK開発] [JNIの分析方法(文字列配列パラメータが渡さ|文字列トラバーサル|文字列を変換するためのJavaとCの文字列| |強いターンを入力した文字列リリース)



文字列のJava配列でI. C / C ++タイプ



Java配列型StringにC / C ++コードでJNI: jobjectArray

①ステータスJNI型: 文字列のJavaのJNI配列に定義されていないタイプは、唯一JSTRING Java文字列型を定義します。

②jオブジェクトに対応するオブジェクト: C / C ++環境でのタイプに対応するjオブジェクトJavaオブジェクトタイプは、Java文字列型オブジェクトです。

③型文字配列: したがって、文字列配列型内のC / C ++環境におけるオブジェクトjobjectArrayの配列を使用して、



II。文字列配列の長さを取得します。



1つの前提条件: Javaの層のパスパラメータjobjectArrayのStringArray、このパラメータは、JavaコードのString []のStringArrayパラメータです。

StringArrayパラメータGetArrayLength方法以下はjobjectArray型です。


2.文字列配列のコード例の長さを得る: 返される値は、タイプint型jsize別名であり;

jsize stringArrayLength = env->GetArrayLength(stringArray);

GetArrayLength方法を詳細に分析以下参照:
GetArrayLength分析法(GET jarray配列の長さ)



III。文字列の配列要素を取得します。



C / C ++コードの指定されたインデックスは、Java文字列配列型要素を取得しました。


1.メソッド呼び出し: 指定されたインデックスjオブジェクト参照型の変数を取得するためGetObjectArrayElementメソッドの呼び出しJNIEnvの* ENV。


。プロトタイプ方法2:

struct _JNIEnv {
    /* _JNIEnv  结构体中封装了 JNINativeInterface 结构体指针 */
    const struct JNINativeInterface* functions;
    ...
    // 最终 调用的 还是 JNINativeInterface 结构体中封装的 GetObjectArrayElement方法
    jobject GetObjectArrayElement(jobjectArray array, jsize index)
    { return functions->GetObjectArrayElement(this, array, index); }
    ...
}

。3つのGetObjectArrayElementパラメータ:

①jobjectArray配列パラメータ:オブジェクトのJavaの層Java配列によって渡されます。

②jsizeインデックスパラメータ:配列要素のインデックス値を取得します。


4.指定されたコードのサンプルオブジェクトの配列要素を取得します。

前記パラメータは、JNIメソッドによって渡さ、jobjectArrayのStringArrayタイプです。

私はint型であるパラメータは、0から数えて、要素を取得するための指標値であることを特徴とします。

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


。IV型の強い回転(jオブジェクト - > JSTRING)



JSTRINGタイプへのjオブジェクト: string_object jオブジェクト型は変数です。

        // 2.2 将 jobject 类型强转成 jstring 类型 , 这两个都代表了 Java 的数据类型
        jstring string_java = static_cast<jstring>(string_object);

以下の詳細なブログへの参照:
[]型C ++言語変換(オペレーター| const_castを| static_castを|のdynamic_cast | reinterpret_castは | 文字列変換)



。V列変換(JSTRING - > CHAR *)



1 ReleaseStringUTFChars方法: (Javaで)JSTRINGタイプ文字列のchar *に型ストリング(文字列C / C ++)。


2.関数プロトタイプ: JSTRING Stringパラメータは、JNIのJava、Java文字列の代表を通過します。

struct _JNIEnv {
    /* _JNIEnv  结构体中封装了 JNINativeInterface 结构体指针 */
    const struct JNINativeInterface* functions;
    ...
    // 最终 调用的 还是 JNINativeInterface 结构体中封装的 GetStringUTFChars 方法
    const char* GetStringUTFChars(jstring string, jboolean* isCopy)
    { return functions->GetStringUTFChars(this, string, isCopy); }
    ...
}

3 jboolean * isCopyパラメータ: このパラメータは、新しいポインタ変数の方法を生成するために、*型ポインタJINTの変数にタイプjintArray変数を指定するために使用されます。


①パラメータポインタがポイントJNI_TRUEに設定されている:int配列データは、新たなメモリ空間にコピーされ、第1のメモリ空間のアドレスを返します。

②パラメータポインタがJNI_FALSEを指すように設定されている:Javaのintのアレイアドレスを直接使用することは、配列のJavaの最初のアドレスを返すINT。

③NULL(推奨)のパラメータは:自動的に一般的な実施形態ではドントケア生成モード選択ポインタを生成する方法を気にしない示します。

④jbooleanタイプ値:jboolean値0及び1のみ、及びJNI_FALSE JNI_TRUEマクロを使用することができます。

#define JNI_FALSE 0
#define JNI_TRUE 1

4文字に文字列をJSTRING *文字列例:

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


VI。文字列リリース



。1 ReleaseStringUTFChars方法: Java文字列とC / C ++の文字列が解放されます。


2.プロトタイプ:

JSTRING文字列パラメータは、JNI、Java文字列に代わってJavaで渡されます。

上記の方法によってCONSTのchar * UTFのGetStringUTFCharsパラメータは、文字列のJava、C / C ++の文字列に変換されます。

struct _JNIEnv {
    /* _JNIEnv  结构体中封装了 JNINativeInterface 结构体指针 */
    const struct JNINativeInterface* functions;
    ...
    // 最终 调用的 还是 JNINativeInterface 结构体中封装的 ReleaseStringUTFChars 方法
    void ReleaseStringUTFChars(jstring string, const char* utf)
    { functions->ReleaseStringUTFChars(this, string, utf); }
    ...
}



VII。サンプルコード部



部品コードの例:

#include <jni.h>
#include <string>

//导入日志库
#include <android/log.h>

//定义日志宏 , 其中的 __VA_ARGS__ 表示可变参数
#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 . 引用类型数组操作 ( 获取字符串数组 )

    // 1 . 获取字符串数组长度
    jsize stringArrayLength = env->GetArrayLength(stringArray);

    // 2 . 遍历字符串数组
    for(int i = 0; i < stringArrayLength; i ++) {

        /*
            2.1 获取 jobject 数组中第 i 个元素
                注意 : 获取的是 jobject 类型变量

            函数原型 : jobject GetObjectArrayElement(jobjectArray array, jsize index)

                jobjectArray array 参数 : 是 Java 层传入的 Java 对象数组 参数 , 即 Native 层的调用函数的参数
                jsize index 参数 : 对象元素的索引值 , 取值范围 0 ~ stringArrayLength - 1

                返回值 : 返回的是 jobject 类型的变量
         */
        jobject string_object = env->GetObjectArrayElement(stringArray, i);

        // 2.2 将 jobject 类型强转成 jstring 类型 , 这两个都代表了 Java 的数据类型
        jstring string_java = static_cast<jstring>(string_object);

        /*
            2.3 将 jstring 类型转为 char* 类型

            jstring 类型简介 :
                class _jobject {};
                class _jstring : public _jobject {};
                typedef _jstring*       jstring;

                由上面可见 , jstring 只是 继承了 _jobject 类 , 没有任何实现 , 是一个空类
                因此需要借助 C/C++ 方法 将 java 类型的 jstring 字符串 其转为 C/C++ 类型的 char* 类型字符串

            转换函数原型 : void ReleaseStringUTFChars(jstring string, const char* utf)
         */
        const char *string_c = env->GetStringUTFChars(string_java, 0);

        // 2.4 打印 转换后的 字符串值
        __android_log_print(ANDROID_LOG_INFO, "JNI_TAG", "打印字符串数组元素 : %d . %s", i, string_c);


        // 2.5 释放 char* 字符串
        env->ReleaseStringUTFChars(string_java, string_c);

    }

}

コードの実行結果:

01-12 19:45:59.634 11885-11885/kim.hsl.jni I/JNI_TAG: 打印 int 数组元素 : 0 . 1
01-12 19:45:59.634 11885-11885/kim.hsl.jni I/JNI_TAG: 打印 int 数组元素 : 1 . 2
01-12 19:45:59.634 11885-11885/kim.hsl.jni I/JNI_TAG: 打印 int 数组元素 : 2 . 666
01-12 19:45:59.634 11885-11885/kim.hsl.jni I/JNI_TAG: 打印 int 数组元素 : 3 . 888
01-12 19:45:59.634 11885-11885/kim.hsl.jni I/JNI_TAG: 打印 int 数组元素 : 4 . 95555
01-12 19:45:59.634 11885-11885/kim.hsl.jni I/JNI_TAG: 打印字符串数组元素 : 0 . Hello
01-12 19:45:59.634 11885-11885/kim.hsl.jni I/JNI_TAG: 打印字符串数组元素 : 1 . World
01-12 19:45:59.634 11885-11885/kim.hsl.jni I/JNI_TAG: 打印字符串数组元素 : 2 . Hanshuliang
01-12 19:45:59.634 11885-11885/kim.hsl.jni I/JNI_TAG: Java 层 jniArrayTest 执行完毕后 , int[] intArray 数组内容 : [8888, 8888, 8888, 8888, 8888]

完全なコードを貼り付けていない、との完全なリソースのセットJNIドキュメントチュートリアル、およびブログのソースでブログをダウンロードするには、スペースの制限

公開された256元の記事 ウォンの賞賛1013 ビュー168万+

おすすめ

転載: blog.csdn.net/han1202012/article/details/104103097