C++ NDK 中 "jobject" 和 "jclass" 有什么区别

What is the difference between "jobject" & "jclass" in C++ NDK

我按照我遵循的教程做了 2 种不同的实现,我注意到每个参数都有点不同,1 个参数是 jclass,另一个是 jobject 我不使用这些参数,但我尝试将它们从 jclass 切换到 jobject 以及从 jobject 切换到 jclass 我注意到一切仍然按预期工作所以我不确定是什么jobjectjinstance 完全一样,如果我的方法没有使用这些参数中的任何一个,为什么需要它们?有人可以在我的 java class 中提供这些方法的正确声明吗?我不确定我是否做对了

JNIEXPORT void JNICALL Java_org_cocos2dx_cpp_AppActivity_pauseSounds(JNIEnv* env, jclass thiz);

JNIEXPORT jstring JNICALL Java_org_cocos2dx_cpp_AppActivity_score(JNIEnv *env, jobject instance);

在 C 中,所有其他 JNI 引用类型定义为与 jobject 相同。例如:

typedef jobject jclass;

在 C++ 中,JNI 引入了一组虚拟 类 来强制执行子类型化关系。例如:

class _jobject {};
class _jclass : public _jobject {};

用法示例:

JNIEnv* env = ...;
// substitute your desired class's specifier for "java/lang/Class"...
jclass cls = env->FindClass("java/lang/Class"); 
jmethodID mid_getName = env->GetMethodID(cls, "getName", "()Ljava/lang/String;");
jstring name = env->CallObjectMethod(cls, mid_getName);

this link goes to oracle documentation of jni for java 6 and this link goes to documentation of jni in java 8 almost the same.

一般来说,

  • 如果JNI函数参数有jclass,则此JNI函数对应Java方class方法(native方法声明 withstatic”)。 jclass 是对 当前 class.
  • 的引用
  • 如果JNI函数参数有jobject,则此JNI函数对应Java端实例方法(声明的本地方法没有静态”)。 jobject 是对 当前实例 .
  • 的引用

具体来说,

JNIEXPORT void JNICALL Java_org_cocos2dx_cpp_AppActivity_pauseSounds(JNIEnv* env, jclass thiz);

对应于 static 本机方法(class 方法)在你的 Java 端,即

package org.cocos2dx.cpp

class AppActivity{
    public static native void pauseSounds();
}

虽然低于 JNI 方法

JNIEXPORT jstring JNICALL Java_org_cocos2dx_cpp_AppActivity_score(JNIEnv *env, jobject instance);

对应你Java这边的原生方法(实例方法),即

package org.cocos2dx.cpp

class AppActivity{
   public native String score();
}

if my method is not using either of these parameters why are they required ?

这些参数是自动生成的,将在需要时由 JNI 使用,例如,在您需要回调 Java 端的情况下 class 方法,你需要像下面这样的东西(()V" 是方法 JNI 签名):

jmethodID staticMethod = env->GetStaticMethodID(clazz, "pauseSounds", "()V");

如果你需要回调Java端实例方法,你需要像下面这样的东西(()Ljava/lang/String;"是方法JNI签名):

env->CallObjectMethod(instance, "score", "()Ljava/lang/String;");