理解JNI

作者: Midlet | 来源:发表于2017-02-21 15:07 被阅读19次

    JNI,是Java Native Interface的缩写
    · Java程序中的函数可以调用Native语言写的函数,Native一般指的是C/C++编写的函数。
    · Native程序中的函数可以调用Java层的函数,也就是在C/C++程序中可以调用Java的函数。

    互调过程
    java做的事

    · 加载对应的JNI库。
    · 声明由关键字native修饰的函数。

    JNI做的事

    . JNI层必须实现为动态库的形式,这样Java虚拟机才能加载它并调用它的函数。
    . 注册JNI函数--之意就是将Java层的native函数和JNI层对应的实现函数关联起来
    . 数据类型转换
    .JNIEnv通过调用CallVoidMethod,CallIntMethod等调用Java对象

    一、注册JNI函数

    1、静态注册

    · 先编写Java代码,然后编译生成.class文件。
    · 使用Java的工具程序javah,如javah–o output packagename.classname ,这样它会生成一个叫output.h 的JNI层头文件。其中packagename.classname是Java代码编译后的class文件,而在生成的output.h文件里,声明了对应的JNI层函数,只要实现里面的函数即可。
    关联关系,其实就是保存JNI层函数的函数指针。以后再调用native_init函数时,直接使用这个函数指针就可以了,当然这项工作是由虚拟机完成的。

    2、动态注册

    动态注册的工作,只用两个函数就能完成
    .jclass clazz = (env)->FindClass(env, className);
    . //调用JNIEnv的RegisterNatives函数,注册关联关系。
    (
    env)->RegisterNatives(env, clazz, gMethods,numMethods);

    当Java层通过System.loadLibrary加载完JNI动态库后,紧接着会查找该库中一个叫JNI_OnLoad的函数,如果有,就调用它,而动态注册的工作就是在这里完成的。

    二、数据类型转换

    在Java中调用native函数传递的参数是Java数据类型,那么这些参数类型到了JNI层会变成什么呢?
    Java数据类型分为基本数据类型和引用数据类型两种

    基本类型对照图 引用类型对照图

    三、JNIEnv介绍

    JNIEnv实际上就是提供了一些JNI系统函数。通过这些函数可以做到:
    · 调用Java的函数。
    · 操作jobject对象等很多事情。

    1、jfieldID 和jmethodID的介绍

    在JNI规则中用jfieldID 和jmethodID 来表示Java类的成员变量和成员函数通过JNIEnv的下面两个函数可以得到:
    jfieldID GetFieldID(jclass clazz,const char*name, const char sig);
    jmethodID GetMethodID(jclass clazz, const char
    name,const char *sig);

    2、使用jfieldID和jmethodID

    JNIEnv通过调用CallVoidMethod,CallIntMethod、CallStatic等再把jobject、jMethodID和对应参数传进去,JNI层就能够调用Java对象的函数了

    相关文章

      网友评论

          本文标题:理解JNI

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