JNI静态加载Natives方法

  1. 优点:和传统方法相比,使用RegisterNatives的好处有三点:
    • C+ 中函数可以自由命名,不必像javah自动生成的函数声明那样,拘泥特定的命名方式;
    • 效率高。传统方式下,Javacall本地函数时,通常是依靠VM去动态寻找“.so”中的本地函数(因此它们才需要特定规则的命名格式),而使用RegisterNatives将本地函数向VM进行登记,可以让其更有效率的找到函数;
    • 运行时动态调整本地函数与Java函数值之间的映射关系,只需要多次call RegisterNatives()方法,并传入不同的映射表参数即可。
  2. 步骤:
    • 指定java中的对应类,classPathName
    • 列出相关方法,Java方法名、输入参数、返回值、JNI方法名;
    • 调用env->FindClass(const char *classPathName)加载类;
    • 调用env->RegisterNatives(jclass clazz, JNINativeMethod[] methods, jint methods_len) ,注册native方法。
  3. 代码示例:  
     1 static const char *classPathName = "com/example/hellojni/HelloFromJNI";
     2 static JNINativeMethod methods[] = {
     3        {"stringFromJNI", "()Ljava/lang/String;", (void*)native_stringFromJNI},
     4 };
     5  
     6 jint RegisterNativeMethods(JNIEnv *env, const char *classPathName ,               
     7 JNINativeMethod methods[], jint methods_len) {
     8     jclass clazz = env->FindClass(classPathName );//加载类名
     9  
    10     if (clazz == NULL) {
    11         LOGE("Native registration unable to find class '%s'", classPathName );
    12         return JNI_ERR;
    13     }
    14  
    15     if (env->RegisterNatives(clazz, methods, methods_len) < 0) { //注册本地native方法
    16         LOGE("RegisterNatives unable to register method %s", classPathName );
    17         return JNI_ERR;
    18     }
    19  
    20     return JNI_OK;
    21 }

     

  注:定义JNINativeMethod时,第二个参数的类型定义如下

    () 中的字符表示输入参数,后面为返回值

    "()V"----> void func()

    "(II)V"----> void func(int, int)   

 

  • Java中的类以 'L' 开头,以 '' 结尾。如, Ljava/lang/String;
  • 其他基本类型,使用其大写首字母,若为数组,则在前面加上 '['

 

Java

符号

JNI

int

 I

jint

byte

 B

jbyte

long

J

jlong

double

D

jdouble

float

F

jfloat

char

C

jchar

short

S

jshort

boolean

Z

jboolean

void

V

void

 

[参]http://www.cnblogs.com/keis/archive/2011/04/12/2013174.html

 

posted @ 2017-10-17 11:57  莎诃  阅读(295)  评论(0)    收藏  举报