Static registration and dynamic registration of JNI development

Posted by ace_lovegrove on Fri, 22 Nov 2019 10:30:21 +0100

Alibaba P7 mobile Internet architect advanced video (in daily update) for free, please click: https://space.bilibili.com/474380680

Static registration

Principle:
According to the function name, the one-to-one correspondence between java method and JNI function is established;

Implementation process:

Write java code;
Using javah instruction to generate corresponding. h file;
Implement the declaration in. h;
Disadvantages:

It is inconvenient to write. JNI method names must follow the rules and have long names;
There are many steps in the compilation process, which is inconvenient;
The running efficiency of the program is low, because it needs to search the corresponding local function in JNI layer according to the function name when calling the native function for the first time, and then establish the corresponding relationship, which is time-consuming;

JNIEXPORT jstring JNICALL
Java_com_example_efan_jni_1learn2_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

Dynamic registration

Principle:
Register the one-to-one correspondence between java method and JNI function by using RegisterNatives method;

Implementation process:

The corresponding relationship between java methods and JNI functions is recorded by using jninanativemethod array;
Implement the JNI uunload method, and perform dynamic registration after loading the dynamic library;
Call FindClass method to get java object;
Call the RegisterNatives method, pass in the java object, the JNINativeMethod array, and the number of registrations to complete the registration;
Advantage:

The process is more clear and controllable;
Higher efficiency;

jstring stringFromJNI(JNIEnv *env, jobject thiz){
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

static const JNINativeMethod gMethods[] = {
        {"stringFromJNI", "()Ljava/lang/String;", (jstring*)stringFromJNI}
};

JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved){

    __android_log_print(ANDROID_LOG_INFO, "native", "Jni_OnLoad");
    JNIEnv* env = NULL;
    if(vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) //Get JNIEnv from JavaVM, generally using version 1.4
        return -1;
    jclass clazz = env->FindClass("com/example/efan/jni_learn2/MainActivity");
    if (!clazz){
        __android_log_print(ANDROID_LOG_INFO, "native", "cannot get class: com/example/efan/jni_learn2/MainActivity");
        return -1;
    }
    if(env->RegisterNatives(clazz, gMethods, sizeof(gMethods)/sizeof(gMethods[0])))
    {
        __android_log_print(ANDROID_LOG_INFO, "native", "register native method failed!\n");
        return -1;
    }
    return JNI_VERSION_1_4;
}

JNINativeMethod

In the process of dynamic registration, the structure jnininativemethod is used to record the correspondence between java methods and jni functions

typedef struct {
    const char* name;
    const char* signature;
    void*       fnPtr;
} JNINativeMethod;

The first parameter name of the structure is the java method name;

The second parameter, signature, is used to describe the parameters and return values of the method;

The third parameter fnPtr is the function pointer, pointing to jni function;

The second parameter, signature, uses string to record the parameters and return values of the method. The specific formats are "() V" and "(II)V", which are divided into two parts. The parameters are shown in parentheses, and the return values are shown in the right side of parentheses;

Data type mapping

1. Basic data type

2. Array reference type

If it is a one-dimensional array, follow the following table. If it is a two-dimensional array or an array of higher dimensions, the corresponding native type is jobjectArray. The number of '[' is used in the domain descriptor to represent the dimension


3. Object reference type

For other reference types, that is, objects in java, the mapping rules are


4. Object array reference type

If it is a one-dimensional array, follow the following table. If it is a two-dimensional array or an array of higher dimensions, the corresponding native type is jobjectArray. The number of '[' is used in the domain descriptor to represent the dimension

jni function default parameters

There are two default parameters in the jni function

JNIEnv *env, jobject thiz

JNIEnv refers to the current java environment, and JNIEnv can be used to operate java layer code; job object refers to the class instance of java native method corresponding to jni function. If java method is static, it represents class object;

Original link: https://blog.csdn.net/qq_2040...

Alibaba P7 mobile Internet architect advanced video (in daily update) for free, please click: https://space.bilibili.com/474380680

Topics: C Java Mobile