JNI_OnLoad() 中的 GetEnv 出错,删除这些行时应用程序崩溃,错误消失

Getting error while GetEnv in JNI_OnLoad() and app crashing when removed these lines, error goes away

应用程序在 JNI_OnLoad() 中崩溃。我检查了它的状态为零。尽管如此,该应用程序仍在崩溃。我想创建环境变量来缓存方法 ID,以便将它们用于 java 函数的回调。我尝试在上下文结构中缓存 jvm 并在 callback() 方法中执行相同操作,但 App 崩溃了。我是这个概念的新手。谁能解释一下我在这里缺少什么。

请查找附件代码:

#include <jni.h>
#include <string>
#include "Numbers.h"

#include <android/log.h>

#define  LOG_TAG    "logs"

#define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)


typedef struct number_ctx{
    JavaVM  *javaVM;
    jclass   mathsClass;
    jobject  mathsObj;
    jclass   mainActivityClass;
    jobject  mainActivityObj;
    pthread_mutex_t  lock;
} NumbersCtx;
NumbersCtx g_ctx;

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
    JNIEnv* env;
    memset(&g_ctx, 0, sizeof(g_ctx));

    g_ctx.javaVM = vm;

    int status = vm ->GetEnv((void **)env, JNI_VERSION_1_6);

    LOGD("Status is %d ", status);
    if (vm ->GetEnv((void **)env, JNI_VERSION_1_6) != JNI_OK) {
        LOGD("Some error");
        return JNI_ERR; // JNI version not supported.
    }

    if(env->ExceptionCheck()) {
        env->ExceptionDescribe();
        env->ExceptionClear();
    }
    /*

    jclass  clz = env->FindClass(
                                    "com/example/maths/Maths1");
    g_ctx.mathsClass = static_cast<jclass>(env->NewGlobalRef(clz));

    jmethodID  jniHelperCtor = env->GetMethodID(g_ctx.mathsClass,
                                                   "printMessage", "()V");
    jobject    handler = env->NewObject(g_ctx.mathsClass,
                                           jniHelperCtor);
    g_ctx.mathsObj = env->NewGlobalRef(handler);

    g_ctx.mainActivityObj = NULL;*/
    return  JNI_VERSION_1_6;
}

void callback() {


}

您在调用 GetEnv 时忘记使用 Address-Of 运算符 (&)。 GetEnv 需要一个指向指针的指针,但您只是将一个指针传递给它,然后将其转换为指向指针的指针,这不是一回事。

所以不用

vm ->GetEnv((void **)env, JNI_VERSION_1_6)

你应该使用

vm ->GetEnv((void **)&env, JNI_VERSION_1_6)

在这种情况下省略 Address-Of 运算符的最终结果是 GetEnv 将存储 JNIEnv* who-knows-where,而您的 env 变量最有可能不会包含有效的 JNIEnv*.