设为首页 加入收藏

TOP

JNI对HAL的封装(三)
2013-04-24 12:13:39 来源: 作者: 【 】 浏览:1162
Tags:JNI HAL 封装

 

  这个文件主要完成的事情有

  1.完成JNI向java的注册:

  jniRegisterNativeMethods,这个函数体现JNI大部分的关键点,主要有env,JNI命名规则,函数签名。

  当VM载入libxxx_jni.so这个库时,就会呼叫JNI_OnLoad()函数。在JNI_OnLoad()中注册本地函数,继续调用到AndroidRuntime::registerNativeMethods(),该函数向VM(即AndroidRuntime)注册gMethods[]数组中包含的本地函数了。AndroidRuntime::registerNativeMethods()起到了以下两个作用:

  1,registerNativeMethods()函数使得java空间中的Native函数更加容易的找到对应的本地函数。(通过gMethods[]中的函数指针)

  2,可以在执行期间进行本地函数的替换。因为gMethods[]数组是一个<java中函数名字,本地函数指针>的对应表,所以可以在程序的执行过程中,多次呼叫registerNativeMethods()函数来更换本地函数的指针,提高程序的弹性。

  2.JNIEnv 介绍

  JNIEnv 是一个与线程相关的变量,由于线程相关,所以线程B中不能使用线程A中的JNIEnv函数。那个多个线程由谁来保存并保证每个线程的JNIEnv结构体正确呢?

  jint JNI_OnLoad(JavaVM* vm, void* reserved)全进程只有一个JavaVM对象,可以保存并在任何地方使用没有问题,独此一份。利用JavaVM中的 AttachCurrentThread函数,就可以得到这个线程的 JNIEnv结构体,利用用DetachCurrnetThread释放相应资源。

  一般通过JNIEnv 操作jobject的jfieldID  操作成员变量和jmethodID  操作成员函数。这个再JNI中创建的每个资源都有自己的ID,在Java空间中通过找到这些ID,就可以找到相对应的成员变量和成员函数。

  static jfieldID GetFieldID(JNIEnv* env, jclass jclazz,const char* name, const char* sig)

  static jmethodID GetMethodID(JNIEnv* env, jclass jclazz, const char* name,const char* sig)

  3.JNI命名规则

  com_android_server_LightsService.cpp,表明这个服务是在com/android/server/下的LightsService.cpp文件,在注册的时候以com/android/server/LightsService作为参数传下去。

  4.函数签名

  因为JAVA支持函数重载,可以定义同名但不同参数的函数,但直接根据函数名是没法找到具体函数的,因此利用参数类型及返回类型组成签名信息。利用JNINativeMethod结构保存其关系。

  typedef struct

  {

  //JAVA中native函数名字

  const char *name;

  //签名信息,用字符串表示,参数类型及返回值类型的组合

  const char *signature;

  ///JNI层函数函数指针,转换为void*类型

  void *fnPtr;

  };

  常用类型标识符:

  类型标识   JAVA类型    字长

  Z        boolean      8位

  B        byte         8位

  C        char         16位 -- 注意哟

  S        short        16位

  I        int          32位

  J        long         64位

  F        float        32位

  D        double       64位

  L/java/languageString  String

  [I       int[]        int数组

  [L/java/lang/object    Object[] 对象数组

  在method_table中主要完成了JNI对HAL的封装函数。

  5.垃圾回收

  finalize_native

  4.JNI其他功能

  1.异常处理

  常用的异常处理函数

  Throw():丢弃一个现有的异常对象;在固有方法中用于重新丢弃一个异常。

  ThrowNew():生成一个新的异常对象,并将其丢弃。

  ExceptionOccurred():判断一个异常是否已被丢弃,但尚未清除。

  ExceptionDescribe():打印一个异常和堆栈跟踪信息。

  ExceptionClear():清除一个待决的异常。

  FatalError():造成一个严重错误,不返回。

  在所有这些函数中,最不能忽视的就是ExceptionOccurred()和ExceptionClear()。大多数JNI函数都能产生异常,而且没有象在Java的try块内的那种语言特性可供利用。所以在每一次JNI函数调用之后,都必须调用ExceptionOccurred(),了解异常是否已被丢弃。若侦测到一个异常,可选择对其加以控制(可能时还要重新丢弃它)。然而,必须确保异常最终被清除。这可以在自己的函数中用ExceptionClear()来实现;若异常被重新丢弃,也可能在其他某些函数中进行。

        

首页 上一页 1 2 3 4 5 下一页 尾页 3/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C++ 验证微软数字签名 下一篇C++检查内存泄露

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: