JNI 函数(六)系统级别的操作

JNI 函数(六)系统级别的操作

(一) 注册方法

函数原型:jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods, jint nMethod);

  根据 clazz 参数注册本地方法,methods 参数制定 JNINativeMethod 结构数组,该数组包含本地方法的名字、签名及函数指针。其中名字及签名是指向编码为 “UTF-8” 的指针;nMethod 参数表明数组中本地方法的个数。

  这里说下 JNINativeMethod 这个结构体

1 typedef struct {
2     const char* name;
3     const char* signature;
4     void*       fnPtr;
5 } JNINativeMethod;

  参数:

    env:JNI 接口指针

    clazz:Java 类对象

    methods:类中的 native 方法

    nMethod:类中本地方法的个数

  返回:

    成功返回 0,失败返回负数

  异常:

    如果没有找到指定的方法或者方法不是本地方法,则抛出 NoSuchMethodError。

(二) 注销方法

函数原型:jint UnregisterNatives(JNIEnv *env, jclass clazz);

  注销本地方法。类回收之前还没有被函数注册的状态。该函数一般不能在 Native 代码中被调用,它为特定的程序提供了一种重加载重链接本地库的方法。

  参数:

    JNI:接口指针

    clazz:Java 类对象

  返回:

    注销成功返回 0,失败返回负数

(三) 监视操作

函数原型:jint MonitorEnter(JNIEnv *env, jobject obj);

  obj 引用的底层 Java 对象关联的监视器。obj 引用不能为空。每个 Java 对象都有一个相关的监视器。如果当前线程已经有关联到 obj 的监视器,它将添加监视器的计数器来表示这个线程进入监视器的次数。如果关联至 obj 的监视器不属于任何线程,那当前线程将变成该监视器的拥有者,并设置计数器为 1,如果其他计数器已经拥有了这个监视器,当前线程将进行等待直到监视器被释放,然后再获得监视器的拥有权。

  通过 MonitorEnter JNI 函数调用的监视器不能用 monitorexitJava 虚拟机指令或者同步方法退出。MonitorEnterJNI 函数调用和 monitorenter Java 虚拟机指令可能用同样的对象竞争地进入监视器。

  为了避免死锁,通过 MoniterEnterJNI 函数调用进入的监视器必须用 MonitorExitJNI 调用退出,除非 DetachCurrentThread 接口被隐式的调用来释放 JNI 监视器

  参数:

    env:JNI 接口指针

    obj:普通的 Java 对象或类对象

  返回:

    成功返回 0,失败返回负数

(四) 监视器退出

函数原型:jint MonitorExit(JNIEnv *env, jobject obj);

  当前线程拥有与该 obj 关联的监视器,线程减少计数器的值来指示线程进入监视器的次数。如果计数器的值变为 0,则线程释放该监视器。Native 代码不能直接调用 MonitorExit 来释放监视器。而是应该通过同步方法来使用 Java 虚拟机指令来释放监视器

  参数:

    env:JNI接口指针

    obj:普通的Java对象或类对象

  返回:

    成功返回0,失败返回负数

  异常:

    如果当前线程不拥有该监视器,则应该抛出 IllegalMonitorStateException

原文地址:https://www.cnblogs.com/Reverse-xiaoyu/p/14134790.html