关于JNI里面的一点疑惑

发布于:2024-08-18 ⋅ 阅读:(73) ⋅ 点赞:(0)

什么是JNI ? JNI就是java和C/C++的交互接口。

最近在复习JNI的使用,之前也用过,都是边学边用,里面很多东西没有仔细理解过。

先贴上JNI代码

//
// Created by fengcheng.cai on 2023/12/15.
//
#define EGL_EGLEXT_PROTOTYPES
#define GL_GLEXT_PROTOTYPES

#include "com_sprd_opengl_test_MyNdk5.h"
#include <ggl.h>
#include <string.h>
#include <unistd.h>
#include <android/bitmap.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#define LOG_TAG "MyNdk5"

struct fileds_t {
    jfieldID mMyNdk5;
    jfieldID mMyNdk6;
    jmethodID mFunc;
};

fileds_t fileds;
jobject gJavaObj = nullptr;

JNIEXPORT void JNICALL Java_com_sprd_opengl_test_MyNdk5_init
        (JNIEnv *env, jobject obj, jobject surface) {
    LOGD("init env: %p, obj: %p", env, obj);
    gJavaObj = env->NewGlobalRef(obj);
}

JNIEXPORT void JNICALL Java_com_sprd_opengl_test_MyNdk5_process
        (JNIEnv *env, jobject obj, jobject bitmap,  jint surfaceW, jint surfaceH) {
    LOGD("process env: %p, obj: %p", env, obj);
    if (env->IsSameObject(gJavaObj, obj)) {
        LOGD("process is same");
    }
}

JNIEXPORT void JNICALL Java_com_sprd_opengl_test_MyNdk5_process2
         (JNIEnv *env, jobject obj) {
    jlong n5 = env->GetLongField(obj, fileds.mMyNdk5);
    jlong n6 = env->GetLongField(obj, fileds.mMyNdk6);
    LOGD("process2 env: %p, obj: %p", env, obj);
    LOGD("process2 n5: %ld, n6: %ld", n5, n6);

    if (env->IsSameObject(gJavaObj, obj)) {
        LOGD("process2 is same");
    }

    env->SetLongField(obj, fileds.mMyNdk5, 88);
    env->SetLongField(obj, fileds.mMyNdk6, 889);

    env->CallVoidMethod(obj, fileds.mFunc, 73, 98);
}

JNIEXPORT void JNICALL Java_com_sprd_opengl_test_MyNdk5_process3
        (JNIEnv *env, jobject obj) {
    LOGD("process3 env: %p, obj: %p", env, obj);
    if (env->IsSameObject(gJavaObj, obj)) {
        LOGD("process3 is same");
    }
}

JNIEXPORT void JNICALL Java_com_sprd_opengl_test_MyNdk5_process4
    (JNIEnv *env, jobject obj) {
    LOGD("process4 env: %p, obj: %p", env, obj);

    if (env->IsSameObject(gJavaObj, obj)) {
        LOGD("process4 is same");
    }
}

JNIEXPORT void JNICALL Java_com_sprd_opengl_test_MyNdk5_uninit
        (JNIEnv *env, jobject obj) {
    jlong n5 = env->GetLongField(obj, fileds.mMyNdk5);
    jlong n6 = env->GetLongField(obj, fileds.mMyNdk6);
    LOGD("uinit env: %p, obj: %p", env, obj);
    LOGD("uinit n5: %ld, n6: %ld", n5, n6);

    env->CallVoidMethod(obj, fileds.mFunc, 72, 99);
}

jint JNI_OnLoad(JavaVM *jvm, void * reserved) {
    JNIEnv *env = nullptr;
    jvm->GetEnv((void**)&env, JNI_VERSION_1_4);

    jclass clazz = env->FindClass("com/sprd/opengl/test/MyNdk5");
    fileds.mMyNdk5 = env->GetFieldID(clazz, "mMyNdk5", "J");
    fileds.mMyNdk6 = env->GetFieldID(clazz, "mMyNdk6", "J");
    fileds.mFunc = env->GetMethodID(clazz, "callback", "(IJ)V");

    LOGD("JNI_OnLoad env: %p", env);
    LOGD("fileds.mMyNdk5: %p", fileds.mMyNdk5);
    LOGD("fileds.mMyNdk6: %p", fileds.mMyNdk6);
    return JNI_VERSION_1_4;
}

我的疑问是jni接口的第二个参数jobject到底是什么?

网上也搜索过问题的答案,都说jobject是java对象,但是我打jobject的地址发现,即使 同一个线程,不同的方法打印的jobject地址都是不一样的

以下是日志打印

 pid       tid
22156-22156//MyNdk5: JNI_OnLoad env: 0xb400007076b8e1d0
22156-22156//MyNdk5: fileds.mMyNdk5: 0xf
22156-22156//MyNdk5: fileds.mMyNdk6: 0x11
22156-22156//MyNdk5: java construct this: com.sprd.opengl.test.MyNdk5@bcd3074
22156-22193//MyNdk5: init env: 0xb400007076b9baf0, obj: 0x6fcc9c4028
22156-22193//MyNdk5: process env: 0xb400007076b9baf0, obj: 0x6fcc9c4008
22156-22193//MyNdk5: process is same


22156-22156//MyNdk5: process2 env: 0xb400007076b8e1d0, obj: 0x7ff0260778
22156-22156//MyNdk5: process2 n5: 19, n6: 97
22156-22156//MyNdk5: process2 is same
22156-22156//MyNdk5: java callback i: 73, j: 98,  this: com.sprd.opengl.test.MyNdk5@bcd3074
22156-22156//MyNdk5: _process2 mMyNdk5: 88, mMyNdk6: 889
22156-22193//MyNdk5: uinit env: 0xb400007076b9baf0, obj: 0x6fcc9c4028
22156-22193//MyNdk5: uinit n5: 88, n6: 889
22156-22193//MyNdk5: java callback i: 72, j: 99,  this: com.sprd.opengl.test.MyNdk5@bcd3074
22156-22156//MyNdk5: process3 env: 0xb400007076b8e1d0, obj: 0x7ff0260b78
22156-22156//MyNdk5: process3 is same
22156-22156//MyNdk5: process4 env: 0xb400007076b8e1d0, obj: 0x7ff0261048
22156-22156//MyNdk5: process4 is same

可以看到,大部分情况jobject是互不相同的,既然它是java对象,而JNI native方法所在的java对象就一个,为啥每次不一样呢?

后来使用 env->IsSameObject 比较了一下发下是一样的,具体原理也不清楚,希望懂的朋友指点一下。


网站公告

今日签到

点亮在社区的每一天
去签到