美文网首页
ndk_002RegisterNatives

ndk_002RegisterNatives

作者: 冉桓彬 | 来源:发表于2017-01-13 13:31 被阅读38次

    http://blog.csdn.net/conowen/article/details/7524744
    http://blog.csdn.net/sno_guo/article/details/7688227
    http://wenku.baidu.com/link?url=NkHvx8fx17eKWEJNWViXB6SmZmkNXCa9rCTiN-uYj9mLV0sNNJ2P5ZgqNftYCshxaZtSO6YnkHAdsbqVYwmvQR-h5Mh3M0EnHjuyV8qsJj7
    当Android的VM执行到程序里的System.loadLibrary("***.so");时, 首先会执行xx.so中的JNI_OnLoad()函数.

    1. RegisterNatives相关概念:
    1. demo:
      完整代码已经传至github:
      https://github.com/ranhuanbin/JniProject/blob/master/app/src/main/jni/jnitest.c
      下面是伪代码
    #define JNI_CLASS_JNITEST "rhb/jni/JniTest"
    #define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
    static void jniTest(JNIEnv *env,jclass clazz){    
           LOGI("[%s]",__FUNCTION__);}
    static JNINativeMethod g_methods[] = {   
           {"javaTest","()V",(void*)jniTest}
    };
    JNIEXPORT jint JNI_OnLoad(JavaVM *vm,void *reserved) {    
           LOGI("[%s]",__FUNCTION__);    
           JNIEnv* env = NULL;    
           (*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4);   
           jclass clazz = (*env)->FindClass(env,JNI_CLASS_JNITEST);    
           (*env)->RegisterNatives(env, clazz, g_methods, NELEM(g_methods));    
           return JNI_VERSION_1_4;
    }
    JNIEXPORT void JNI_OnUnload(JavaVM *jvm, void *reserved) {    
           LOGI("[%s]",__FUNCTION__);
    }
    

    (*env)->RegisterNatives:向VM(即AndroidRuntime)登记g_methods表格所含的本地方法.

    1. RegisterNatives函数原型:
    jint RegisterNatives(jclass clazz, const JNINativeMethod* methods, jint nMethods)
    

    clazz: 告诉VM, clazz类中使用了g_methods中的本地方法;
    methods: 定义了java语言和本地语言(c/c++)的映射关系, 后面详细介绍.
    nMethods: g_methods数组元素个数;

    2.g_methods():
    static JNINativesMethods g_methods[] = {
        {"javaTest","()V",(void*)jniTest};
    };
    

    javaTest: 这个是java中clazz的方法;
    jniTest: 这个是本地方法;
    ()V: 这个表示java函数原型.

    3.(**)V:

    本地方法中数据类型有基本数据类型和引用数据类型; 注意这里是映射关系, 与之前的java与本地数据类型的区别;

    1. ()里面的数据表示java方法中的形参类型, java方法的返回类型;
      例如
    (i,i)V则表示java方法原型是public void method(int a, int b);
    
    1. 第二个参数详解:
      基本数据类型:
    Field Descriptor               Java Language Type
    Z                ->            boolean
    B                ->            byte
    C                ->            char
    S                ->            short
    I                ->            int
    J                ->            long
    F                ->            float
    D                ->            double
    

    引用数据类型:

    Field Descriptor                         Java Language Type
    Ljava/lang/String         ->             String
      [I                        ->             int[]
    [Ljava/lang/Object        ->             Object[]  
    

    Example:

    "()Ljava/lang/String;"   ->  String function();
    "(ILjava/lang/Class;)J"  ->  long function(int a, Class clazz);
    "([B)V"                  ->  void function(byte[] bys); 
    

    相关文章

      网友评论

          本文标题:ndk_002RegisterNatives

          本文链接:https://www.haomeiwen.com/subject/syljbttx.html