Android NDK JNI Eintrag Notizen -day03- Referenzdatentypen

* Android NDK JNI Verzeichniseintrag Notizen *

Java & JNI Referenzdatentypen

um verschiedene Arten von Java-Objekten entspricht, enthält JNI Referenztyp eine große Anzahl von

java-jni-Referenz-Typen

Java-Klasse-Typ JNI Referenztypen Typ Beschreibung
java.lang.Object jobject jedes Java-Objekt darstellen kann, oder es gibt keine entsprechende Art von Java-Objekte JNI (Pflichtparameter Beispiele für Verfahren)
java.lang.String jstring Java ist ein Objekt vom Typ String String
java.lang.Class JClass Java-Klassenobjekttyp (Pflichtparameter statische Methode)
Objekt[] jobjectArray Array Darstellung jedes Java-Objekt
boolean [] jbooleanArray Java primitive Typen boolean Array-Darstellung
Byte[] jbyteArray Array-Darstellung von Java primitiver Typenbyte
verkohlen[] jcharArray Array-Darstellung von Java primitivem Typ char
kurz[] jshortArray Array-Darstellung von Java Urtyp kurz
int [] jintArray Array-Darstellung von Java primitivem Typ int
lange[] jlongArray Array-Darstellung von Java Urtyp lange
schweben[] jfloatArray Array-Darstellung von Java primitivem Typ float
doppelt[] jdoubleArray Array-Darstellung von Java primitiver Art Doppel
java.lang.Throwable jthrowable Java-Typ Throwable, repräsentieren alle Arten und abnormal Unterkategorien

JNI Referenztypen von Basisdatentyp Array -Java

Schreiben Sie ein paar Beispiele JNI Array-Operationen zu fühlen.

day03-Array

Ruft ein Array von Native, Java-Format

/**
 * 从 Native 获取数组,Java 进行格式化
 * @param view
 */
public void getNativeArray(View view) {
    boolean[] nativeArray = NativeUtil.getNativeArray();
    StringBuilder stringBuilder = new StringBuilder("[");
    for(int i = 0; i < nativeArray.length; i++) {
        stringBuilder.append(nativeArray[i]);
        if(i != nativeArray.length -1) {
            stringBuilder.append(", ");
        }
    }
    stringBuilder.append("]");
    getNativeArrayText.setText(stringBuilder.toString());
}

// JNI 对数组的操作
extern "C"
JNIEXPORT jbooleanArray JNICALL
Java_com_ihubin_ndkjni_NativeUtil_getNativeArray(JNIEnv *env, jclass clazz) {
    jboolean* jb = new jboolean[5];
    jb[0] = JNI_TRUE;
    jb[1] = JNI_FALSE;
    jb[2] = JNI_TRUE;
    jb[3] = JNI_FALSE;
    jb[4] = JNI_TRUE;

    jbooleanArray jba = env->NewBooleanArray(5);
    env->SetBooleanArrayRegion(jba, 0, 5, jb);

    return jba;
}

Das Java-Array übergeben Ureinwohner, Ureinwohner Format

/**
 * 将 Java 数组传入 Native,Native 格式化
 * @param view
 */
public void formatArray(View view) {
    int[] intArray = {11, 22, 33, 44, 55};
    String formatArrayStr = NativeUtil.formatArray(intArray);
    formatArrayText.setText(formatArrayStr);
}

// JNI 对数组的操作
Java_com_ihubin_ndkjni_NativeUtil_formatArray(JNIEnv *env, jclass clazz, jintArray int_array) {
    jint array[5];
    env->GetIntArrayRegion(int_array, 0, 5, array);
    jsize size = env->GetArrayLength(int_array);
    char resutStr[100] = {0};
    char str[10] = {0};
    strcat(resutStr, "[");
    for(int i = 0; i < size; i++) {
        sprintf(str, "%d", array[i]);
        strcat(resutStr, str);
        if(i != size - 1) {
            strcat(resutStr, ", ");
        }
    }
    strcat(resutStr, "]");
    return env->NewStringUTF(resutStr);
}

Einheimische den Gesamtpreis der Waren zu berechnen

/**
 * Native 计算商品总价
 * @param view
 */
public void calcTotalMoney(View view) {
    double[] price = {5.5, 6.6, 7.7, 8.8, 9.9};
    String resultStr = NativeUtil.calcTotalMoney(price);
    calcTotalMoneyText.setText(resultStr);
}

// JNI 对数组的操作
extern "C"
JNIEXPORT jstring JNICALL
Java_com_ihubin_ndkjni_NativeUtil_calcTotalMoney(JNIEnv *env, jclass clazz, jdoubleArray price) {
    jdouble array[5];
    env->GetDoubleArrayRegion(price, 0, 5, array);
    jsize size = env->GetArrayLength(price);

    char resutStr[255] = {0};
    char str[20] = {0};
    strcat(resutStr, "sum(");
    jdouble totalMoney = 0.0;
    for(int i = 0; i < size; i++) {
        sprintf(str, "%.1f", array[i]);
        strcat(resutStr, str);
        if(i != size - 1) {
            strcat(resutStr, ", ");
        }
        totalMoney += array[i];
    }
    strcat(resutStr, ")");
    strcat(resutStr, "\n=");
    sprintf(str, "%.1f", totalMoney);
    strcat(resutStr, str);
    return env->NewStringUTF(resutStr);
}

Einheimische, ob alle Fächer zu berechnen durch

/**
 * 计算各科成绩是否通过
 * @param view
 */
public void calcScorePass(View view) {
    float[] yourScore = {59.0F, 88.0F, 76.5F, 45.0F, 98.0F};
    String[] yourScoreResult = NativeUtil.calcScorePass(yourScore);
    StringBuilder stringBuilder = new StringBuilder();

    stringBuilder.append("[");
    for(int i = 0; i < yourScore.length; i++) {
        stringBuilder.append(yourScore[i]);
        if(i != yourScore.length - 1) {
            stringBuilder.append(", ");
        }
    }
    stringBuilder.append("]");

    stringBuilder.append("\n");

    stringBuilder.append("[");
    for(int i = 0; i < yourScoreResult.length; i++) {
        stringBuilder.append(yourScoreResult[i]);
        if(i != yourScoreResult.length - 1) {
            stringBuilder.append(", ");
        }
    }
    stringBuilder.append("]");

    calcScorePassText.setText(stringBuilder.toString());
}


extern "C"
JNIEXPORT jobjectArray JNICALL
Java_com_ihubin_ndkjni_NativeUtil_calcScorePass(JNIEnv *env, jclass clazz, jfloatArray your_score) {
    jfloat array[5];
    env->GetFloatArrayRegion(your_score, 0, 5, array);
    jsize size = env->GetArrayLength(your_score);

    jclass objClass = env->FindClass("java/lang/String");
    jobjectArray objArray = env->NewObjectArray(5, objClass, 0);
    jstring  jstr;
    for(int i = 0; i < size; i++) {
        if(array[i] >= 60.0) {
            jstr = env->NewStringUTF("√");
        } else {
            jstr = env->NewStringUTF("×");
        }
        env->SetObjectArrayElement(objArray, i, jstr);
    }

    return objArray;
}

Schauen Sie sich die Ergebnisse:

day03-array-result

Hier haben wir ‚gemeistert‘ die grundlegenden Java JNI verschiedene Operationen auf den Datentyp des Arrays.

In Native 计算各科成绩是否通过diesem Beispiel hat es einen Code gewesen jclass objClass = env->FindClass("java/lang/String");hier zu erkunden.

JNI Referenztypen -Java Objekte

Bevor alle Methodenaufrufe in der Java Native, jetzt, anti-nativen Code ist Code, der die Java-Schicht aufruft.

Klasse / Eigenschaften und Methoden / Objekt

Erstens Zugang des Klassenobjekt

Um in Java-Klassen in C / C ++ in definiert jni.h Header-Datei eine Darstellung JClass spezielle Art in Java Class Klasse aufrufen zu können. Es gibt drei JNIEnv Funktion JClass zu erhalten.

// 通过类的名称(类的全名,这时候包名不是用'"."点号而是用"/"来区分的)来获取 jclass
jclass FindClass(const char* clsName)

// 通过对象实例来获取 jclass,相当于 Java 中的 getClass() 函数
jclass GetObjectClass(jobject obj)

// 通过 jclass 可以获取其父类的 jclass 对象
jclass getSuperClass(jclass obj)

Beispiel:

// 获取 Java 中的类 java.lang.String
jclass objClass = env->FindClass("java/lang/String");

// 获取一个类的父类
jclass superClass = env->getSuperClass(objClass);

Zweitens erhalten Eigenschaft Methode

++ erworben Java Schichteigenschaften und Methoden in der C / C, JNI jfieldID und definieren zwei Typen jmethodID jni.h Header-Datei das Ende der Java-Eigenschaften und Methoden darzustellen.

// 获取属性
jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)

// 获取方法
jmethodID GetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)

// 获取静态属性
jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)

// 获取静态方法
jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz,const char *name, const char *sig)

Beispiel:

package com.ihubin.ndkjni;

public class User {

    public static int staticField = 88;

    public int normalField = 99;

    public static String getStaticUserInfo() {
        return "[name:hubin, age:18]";
    }
    
    public String getNormalUserInfo() {
        return "[name:hubin, age:28]";
    }    
    
     private String name;

    private int age;

    public User() {}

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getFormatInfo() {
        return String.format("[name:%s, age:%d]", name, age);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    
}


// 获取 jclass
jclass userClass = env->FindClass("com/ihubin/ndkjni/User");

// 获取属性 ID
jfieldID normalField = env->GetFieldID(userClass, "normalField", "I");
// 获取静态属性 ID
jfieldID staticField = env->GetStaticFieldID(userClass, "staticField", "I");

// 获取方法 ID
jmethodID normalMethod = env->GetMethodID(userClass, "getNormalUserInfo", "()Ljava/lang/String;");
// 获取静态方法 ID
jmethodID staticMethod = env->GetStaticMethodID(userClass, "getStaticUserInfo", "()Ljava/lang/String;");

// 获取无参构造函数
jmethodID voidInitMethod = env->GetMethodID(userClass, "<init>", "()V");
// 获取有参构造函数
jmethodID paramInitMethod = env->GetMethodID(userClass, "<init>", "(Ljava/lang/String;I)V");

Drittens konstruieren, um das Objekt

Für den Zugriff auf das Innere der nachfolgenden nicht-statische Instanz der Klasse Attribute, Methoden, nach JClass durch die obige Aufgabe zu erhalten ist so aufgebaut und konfiguriert ist, um Funktion jmethodID.

// 通过 clazz/methodID/...(可变参数列表) 创建一个对象
jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...);

// args(参数数组)
jobject NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);

// args(指向变参列表的指针)
jobject NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);

// 通过一个类创建一个对象,默认构造函数
jobject AllocObject(JNIEnv *env, jclass clazz)

Beispiel:

// 通过无参构造函数
jobject userOne = env->NewObject(userClass, voidInitMethod);

// 通过有参构造函数
jstring name = env->NewStringUTF("HUBIN");
jint age = 8;
jobject userTwo = env->NewObject(userClass, paramInitMethod, name, age);

// 默认构造函数
jobject userThree = env->AllocObject(userClass);

Viertens acquire Eigenschaft, rufen Sie die Methode

Vor der Zubereitung ist in der Lage sein, Java zu verwenden Objekteigenschaften und -methoden.

Erhalten Sie, setzen Sie die Eigenschaftswerte:
XXX Get<type>Field(jobject obj, jfieldID fieldID)
Set<type>Field(jobject obj, jfieldID fieldID, XXX value)

Erhalten, eine statische Eigenschaft Wert gesetzt:
XXX GetStatic<type>Field(jclass clazz, jfieldID fieldID)
SetStatic<type>Field(jclass clazz, jfieldID fieldID, XXX value)

Rufen Sie die Methode:
NativeType Call<type>Method(JNIEnv *env, jobject obj, jmethodID methodID, ...)
NativeType Call<type>MethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args)
NativeType Call<type>MethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)

Rufen Sie die statische Methode:
NativeType CallStatic<type>Method(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
NativeType CallStatic<type>MethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
NativeType CallStatic<type>MethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)

Beispiel:

// 获取对象中的属性
jint normalFieldValue = env->GetIntField(userOne, normalField);
LOGD("normalField: %d", normalFieldValue);

// 获取 class 中静态属性
jint staticFieldValue = env->GetStaticIntField(userClass, staticField);
LOGD("staticField: %d", staticFieldValue);

// 调用对象中的方法
jobject normalMethodResultObj = env->CallObjectMethod(userOne, normalMethod);
jstring normalMethodResult = static_cast<jstring>(normalMethodResultObj);
const char *normalMethodResultNativeString = env->GetStringUTFChars(normalMethodResult, 0);
LOGD("normalMethodResult: %s", normalMethodResultNativeString);

// 调用 class 中的静态方法
jobject staticMethodResultObj = env->CallStaticObjectMethod(userClass, staticMethod);
jstring staticMethodResult = static_cast<jstring>(staticMethodResultObj);
const char *staticMethodResultNativeString = env->GetStringUTFChars(staticMethodResult, 0);
LOGD("staticMethodResult: %s", staticMethodResultNativeString);

// 调用对象中的方法
jobject getFormatInfoMethodResultObj = env->CallObjectMethod(userTwo, getFormatInfoMethod);
jstring getFormatInfoMethodResult = static_cast<jstring>(getFormatInfoMethodResultObj);
const char *getFormatInfoMethodResultNativeString = env->GetStringUTFChars(getFormatInfoMethodResult, 0);
LOGD("getFormatInfoMethodResult: %s", getFormatInfoMethodResultNativeString);

// 测试 jobject AllocObject(JNIEnv *env, jclass clazz) 创建的对象
jobject userThreeMethodResultObj = env->CallObjectMethod(userThree, normalMethod);
jstring userThreeMethodResult = static_cast<jstring>(userThreeMethodResultObj);
const char *userThreeMethodResultNativeString = env->GetStringUTFChars(userThreeMethodResult, 0);
LOGD("userThreeMethodResult: %s", userThreeMethodResultNativeString);

day03-example-Ergebnis

Wenn jfieldID, jmethodID zu erhalten, gab es einige seltsame Saiten I ()Ljava/lang/String; ()V (Ljava/lang/String;I)V, kommen Blick unten.

Datentyp Unterschrift

In der JVM virtuellen Maschine, wenn der Name des gespeicherten Datentypen Signaturtyp zum Speichern angegeben wird, anstatt unsere Gewohnheit, int, float und so weiter.
JNI verwendet diese Art der Signatur.

Java-Typ Typ Unterschrift
int ich
lange J
Byte B
kurz S
verkohlen C
schweben F
doppelt D
boolean mit
Leere V
Mehr Referenzen L + + Klasse volle Namen;
Feld [
Verfahren (Parameter) Rückgabewert

Beispiel 1

Java 类型:java.lang.String
类型签名:Ljava/lang/String;
即一个 Java 类对应的签名,就是 L 加上类的全名,其中 . 要换成 / ,最后不要忘掉末尾的分号。

Beispiel 2

Java 类型:String[]
类型签名:[Ljava/lang/String;

Java 类型:int[][]
类型签名:[[I

数组就是简单的在类型描述符前加 [ 即可,二维数组就是两个 [ ,以此类推。

Beispiel 3

Java 方法:long f (int n, String s, int[] arr);
类型签名:(ILjava/lang/String;[I)J

Java 方法:void f ();
类型签名:()V

括号内是每个参数的类型符,括号外就是返回值的类型符。

Verwenden javap -s <Class>Signatur anzeigen

javap-get-Methode-Unterschrift

Bisher haben wir gelernt, Java-Objekte in nativer Android-Projekt zu manipulieren.


Code:

NDKJNIday03

Referenzen:

Oracle - JNI Typen und Datenstrukturen

JNI Basis: JNI-Datentyp-Deskriptor-Typ und

Android JNI Lernen (drei) - Java und Native Aufruf einander

JNI Complete Guide (vier) - Objektmanipulation


Ich denke du magst

Origin www.cnblogs.com/binglingziyu/p/android-ndk-jni-basic-day03.html
Empfohlen
Rangfolge