7

I did 2 different implementations from tutorials I followed and I noticed the parameters are a little different for each one, 1 parameter is jclass and the other is jobject I don't use these parameters at all, but I tried experimenting and switching them from jclass to jobject and jobject to jclass and I noticed everything still works as expected so I'm not sure what exactly jobject and jinstance do exactly, also if my method is not using either of these parameters why are they required ? and can someone please provide the correct declaration of these methods in my java class i'm unsure if I did it right

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);
Zoe
  • 27,060
  • 21
  • 118
  • 148
isJulian00
  • 924
  • 2
  • 10
  • 24

2 Answers2

15

Generally,

  • if the JNI function arguments have jclass, then this JNI function corresponds to the Java side class method (the native methods declared with "static"). jclass is a reference to the current class.
  • if the JNI function arguments have jobject, then this JNI function corresponds to the Java side instance method (the native methods declared without "static"). jobject is a reference to the current instance.

Specifically,

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

corresponds to the static native method (class method) on your Java side, i.e.

package org.cocos2dx.cpp

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

While below JNI method

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

corresponds to the native method (instance method) on your Java side, i.e.

package org.cocos2dx.cpp

class AppActivity{
   public native String score();
}

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

These parameters are auto generated and will be used by JNI if needed, for example, in the case that you need to call back the Java side class methods, you need something like below (()V" is the method JNI signature):

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

in the case that you need to call back the Java side instance methods, you need something like below(()Ljava/lang/String;" is the method JNI signature):

env->CallObjectMethod(instance, "score", "()Ljava/lang/String;");
shizhen
  • 12,251
  • 9
  • 52
  • 88
  • thank you very much for the detailed explanation !, how come I don't have to declare static next to JNIEXPORT if the method is declared as static in the java code ? – isJulian00 May 21 '19 at 03:40
  • 1
    You don't need to *declare* static in the JNI part, and the static characteristics can be told by the `jclass` argument and JNI will recognise this method is a class method. Also please note that the term `static` is different on Java and C/C++ semantics. – shizhen May 21 '19 at 03:44
  • do we need a semicolon when we write "extern "C" { };" or should we write it like "extern "C" { }" ??? – isJulian00 May 22 '19 at 18:41
  • Don't need semicolon – shizhen May 23 '19 at 01:10
  • Would you be able to help with this question ? https://stackoverflow.com/questions/56266237/how-do-i-include-a-call-to-make-sure-checksum-matches-apk – isJulian00 May 23 '19 at 05:07
1

In C, all other JNI reference types are defined to be the same as jobject. For example:

typedef jobject jclass;

In C++, JNI introduces a set of dummy classes to enforce the subtyping relationship. For example:

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

a sample of usage:

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.

Aneury Perez
  • 82
  • 2
  • 5
  • can you show how the java declaration would look for each method ? im not sure if their suppose to be different for each one – isJulian00 May 21 '19 at 03:34
  • what im confused about is the jstring method is declared as static in java, but do I have to also declare it as static next to JNIEXPORT OR JNICALL ? – isJulian00 May 21 '19 at 03:38
  • 1
    no, you don't have to declare as static, JNIEXPORT and JNICALL are just decorator with some information JNIEXPORT is define as` __attribute__ ((visibility ("default")))` in my installation and `JNICALL __stdcall`, **__attribute__** is and attribute that is define for some compiler and **__stdcall** is the calling convention used for the function. This tells the compiler the rules that apply for setting up the stack, pushing arguments and getting a return value. – Aneury Perez May 21 '19 at 03:45