当前位置:网站首页>NDK learning notes (I)

NDK learning notes (I)

2022-06-11 05:33:00 Come and go

1.java The relationship between method and native instance method parameters .

java The instance method corresponds to jobject,java Static method correspondence jclass.

 public static native String stringFromJNI();
 
extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_testndk_JniUtil_stringFromJNI(JNIEnv *env, jclass thiz){
    }
public native String stringFromJNI();

extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_testndk_JniUtil_stringFromJNI(JNIEnv *env, jobject thiz) {
    }

2.java And c/c++ Basic data type relationships for

 Insert picture description here

3.java The relationship between application type and native

 Insert picture description here

4. String related operations

hold java The string is converted to C character string

    //JNI_TRUE  The returned string address points to the copy 
    //JNI_FALSE  The returned string address points to a fixed object in the heap 
    jboolean bo = JNI_FALSE;

    // Create string 
    jstring ss = env->NewStringUTF("hello world");
    // take jstring Convert to an operable string 
    const char *str = env->GetStringUTFChars(ss, &bo);
    if (str != 0) {
    

        printf("111111111111111%s", str);
    }

Release string ( Unlike java There's a garbage collector , Application requires release )

env->ReleaseStringUTFChars(ss,str);

5. Array operation

(1) Create array

New<Type>Array
Type: Corresponding Int、Char、Bollean etc. 

Using examples :

    jintArray array = env->NewIntArray(10);

(2) Access array ( copy )

        // Convert array 
        jint nativeARRAY[5];
        env->GetIntArrayRegion(array, 0, 5, nativeARRAY);
        // Operation array , from C Array orientation java Array commit changes 
        nativeARRAY[0] = 100;
        env->SetIntArrayRegion(array, 0, 5, nativeARRAY);

java

        int[] array = {
    10, 11, 12, 13, 14};
        arrayOperation(array);
        for (int i = 0; i < 5; i++) {
    

            Log.i("mainActivity", array[i] + "");
        }

Output results

2020-03-14 17:35:12.173 18150-18150/com.example.testndk I/mainActivity: 100
2020-03-14 17:35:12.173 18150-18150/com.example.testndk I/mainActivity: 11
2020-03-14 17:35:12.173 18150-18150/com.example.testndk I/mainActivity: 12
2020-03-14 17:35:12.173 18150-18150/com.example.testndk I/mainActivity: 13
2020-03-14 17:35:12.175 18150-18150/com.example.testndk I/mainActivity: 14

(3) Access array ( Operation on direct pointer )

        // Get a direct pointer 
        jint *myInt = env->GetIntArrayElements(array, JNI_FALSE);
        // Operation array , Commit changes and free memory 
        myInt[0] = 1555;
        env->ReleaseIntArrayElements(array, myInt, 0);

java

        int[] array = {
    10, 11, 12, 13, 14};
        arrayOperation(array);
        for (int i = 0; i < 5; i++) {
    

            Log.i("mainActivity", array[i] + "");
        }

Output results

2020-03-14 20:45:50.064 19088-19088/com.example.testndk I/mainActivity: 1555
2020-03-14 20:45:50.065 19088-19088/com.example.testndk I/mainActivity: 11
2020-03-14 20:45:50.065 19088-19088/com.example.testndk I/mainActivity: 12
2020-03-14 20:45:50.065 19088-19088/com.example.testndk I/mainActivity: 13
2020-03-14 20:45:50.065 19088-19088/com.example.testndk I/mainActivity: 14

ReleaseIntArrayElements The third parameter mode explain .
 Insert picture description here

6.NIO operation

    // Create a direct byte buffer 
    unsigned char *buffer = (unsigned char *) malloc(1024);
    jobject objBuffer = env->NewDirectByteBuffer(buffer, 1024);
    // Get buffer 
    unsigned char *buffer2 = (unsigned char *)env->GetDirectBufferAddress(objBuffer);

7. access domains

extern "C" JNIEXPORT void JNICALL
Java_com_example_testndk_MainActivity_fieldOperation(
        JNIEnv *env,
        jobject /* this */, jobject obj) {
    

    // Instance domain 
    // Get domain id,Ljava/lang/String;
    jclass cls = env->GetObjectClass(obj);
    jfieldID fId = env->GetFieldID(cls, "size", "Ljava/lang/String;");
    // Get domain 
    jstring str = (jstring) env->GetObjectField(obj, fId);
    const char *c = env->GetStringUTFChars(str, JNI_FALSE);
    LOGI("%s", c);

    // Static domain 
    // Get domain id
    jfieldID fId2 = env->GetStaticFieldID(cls, "staticSize", "Ljava/lang/String;");
    // Get domain 
    jstring str2 = (jstring) env->GetStaticObjectField(cls, fId2);
    const char *c2 = env->GetStringUTFChars(str2, JNI_FALSE);
    LOGI("%s", c2);
}

java

public class MyBox {
    

    private String size = "instance";
    private static String staticSize = "static";
}
        MyBox myBox = new MyBox();
        fieldOperation(myBox);

Output results

2020-03-14 23:53:00.647 21624-21624/com.example.testndk I/test-jni: instance
2020-03-14 23:53:00.647 21624-21624/com.example.testndk I/test-jni: static

8. Calling method

extern "C" JNIEXPORT void JNICALL
Java_com_example_testndk_MainActivity_methodOperation(
        JNIEnv *env,
        jobject /* this */, jobject obj) {
    
    // obtain class
    jclass cls = env->GetObjectClass(obj);
    // Get instance method id
    jmethodID mId = env->GetMethodID(cls, "instanceMethod", "()Ljava/lang/String;");
    // Invoking an instance method 
    jstring result = (jstring) env->CallObjectMethod(obj, mId);
    const char *c = env->GetStringUTFChars(result, JNI_FALSE);
    LOGI("%s",c);


    // Get static methods id
    jmethodID mId2 = env->GetStaticMethodID(cls, "staticMethod", "()Ljava/lang/String;");
    // Call static methods 
    jstring result2 = (jstring) env->CallStaticObjectMethod(cls, mId2);
    const char *c2 = env->GetStringUTFChars(result2, JNI_FALSE);
    LOGI("%s",c2);
}

java

public class MyBox {
    


    private String instanceMethod() {
    

        return "instance";
   }

    private static String staticMethod() {
    

        return "static";
    }
}
        MyBox myBox = new MyBox();
        methodOperation(myBox);

Output content

2020-03-15 13:50:54.937 21991-21991/com.example.testndk I/test-jni: instance
2020-03-15 13:50:54.937 21991-21991/com.example.testndk I/test-jni: static

9. Domain and method descriptors

 This type of data is a descriptor 
()Ljava/lang/String;
Ljava/lang/String;

android studio Descriptor configuration for , Makes it easier to get descriptors .
file→setting→tools→external tools
Click on + Number ,name at will , Others are as follows :

program:$JDKPath$/bin/javap
arguments:-s -p $FileClass$
working directory:$ModuleFileDir$\build\intermediates\javac\debug\classes

Click on ok, complete .
Use : Click menu tools→external tools→ Your name
effect :

D:\Android_develop\android_studio\jre/bin/javap -s -p com.example.testndk.MyBox
Compiled from "MyBox.java"
public class com.example.testndk.MyBox {
    
  public com.example.testndk.MyBox();
    descriptor: ()V

  private java.lang.String instanceMethod();
    descriptor: ()Ljava/lang/String;

  private static java.lang.String staticMethod();
    descriptor: ()Ljava/lang/String;
}

Process finished with exit code 0

10. Use in native code log

#include <android/log.h>

#define LOG "test-jni" //  This is a custom LOG The logo of 
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG,__VA_ARGS__) //  Definition LOGD type 
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG,__VA_ARGS__) //  Definition LOGI type 
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG,__VA_ARGS__) //  Definition LOGW type 
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG,__VA_ARGS__) //  Definition LOGE type 
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG,__VA_ARGS__) //  Definition LOGF type 

Use

    LOGI("%s",c);
原网站

版权声明
本文为[Come and go]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/03/202203020538240086.html