阅读 65

JNI 静态注册/动态注册

静态注册

静态注册 native 方法的过程,就是 Java 层声明的 native 方法和 JNI 函数是一一对应的

public class HelloJNI {
    static{
        System.loadLibrary("main");
    }

    public native void dynamicLog();
    public native void staticLog();}

#include <jni.h>#define LOG_TAG "main.cpp"#include "mylog.h"JNIEXPORT void JNICALL Java_com_wwe_HelloJNI_staticLog (JNIEnv *env, jobject obj){
    LOGE("static register log ");}

那么有没有方法让 Java 层的 native 方法和任意的 JNI 函数链接起来,当然是可以的,这就得使用动态注册的方法。接下来就看看如何实现动态注册的。

动态注册

因为 Java 层和 C/C++ 的数据类型或者对象不能直接相互的引用或者使用,JNI 层定义了自己的数据类型,用于衔接 Java 层和 JNI 层。了解一下JNI_OnLoad函数

#include <jni.h>#define LOG_TAG "main.cpp"#include "mylog.h"static void nativeDynamicLog(JNIEnv *evn, jobject obj){
    LOGE("hell main");}// 一般会动态注册多个 native 方法JNINativeMethod nativeMethod[] = {{"dynamicLog", "()V", (void*)nativeDynamicLog},};JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
    JNIEnv *env;
    if (jvm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        return -1;
    }
    LOGE("JNI_OnLoad comming");
    jclass clz = env->FindClass("com/wwe/HelloJNI");

    // 第三个参数为注册 native 方法的数量
    env->RegisterNatives(clz, nativeMethod, sizeof(nativeMethod)/sizeof(nativeMethod[0]));
    return JNI_VERSION_1_4;}

JavaVM 结构体定义了以下函数:

DestroyJavaVM
AttachCurrentThread
DetachCurrentThread
GetEnv

获取Java对象,完成动态注册

jint RegisterNatives(jclass clazz, const JNINativeMethod* methods, jint nMethods)

JNINativeMethod 结构体是描述 Java 层 native 方法的,它的定义如下:

typedef struct {
    const char* name; // Java 层 native 方法的名字
    const char* signature; // Java 层 native 方法的描述符
    void*       fnPtr; // 对应JNI 函数的指针} JNINativeMethod;

JNIEnv 结构体

它指向一个函数表,该函数表指向一系列的 JNI 函数,我们通过调用这些 JNI 函数可以实现与 Java 层的交互,这里简单的看看几个定义的函数:

// CallVoidMethod() 根据 methodID 调用对应对象中的方法,并且该方法的返回值为 Void 类型。..........jfieldID GetFieldID(jclass clazz, const char* name, const char* sig)jboolean GetBooleanField(jobject obj, jfieldID fieldID)jmethodID GetMethodID(jclass clazz, const char* name, const char* sig)CallVoidMethod(jobject obj, jmethodID methodID, ...)CallBooleanMethod(jobject obj, jmethodID methodID, ...)..........



作者:Drew_MyINTYRE
链接:https://www.jianshu.com/p/873fc6ee4e51

文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐