Is there any way I can know the name of the class that called a method in JNI C code ? I can obtain a reference to the class using the following statement :
jclass cls = (*env)->GetObjectClass(env,obj);
But is there any way I can know the name of the class ? .
The simplest way is to call the getClass() method that returns the class's name or interface represented by an object that is not an array. We can also use getSimpleName() or getCanonicalName() , which returns the simple name (as in source code) and canonical name of the underlying class, respectively.
Yes, It is allowed to define a method with the same name as that of a class.
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 {}; ...
jobject NewGlobalRef(JNIEnv *env, jobject obj); Creates a new global reference to the object referred to by the obj argument. The obj argument may be a global or local reference.
This code will give you the calling class name:
jclass cls = env->GetObjectClass(obj);
// First get the class object
jmethodID mid = env->GetMethodID(cls, "getClass", "()Ljava/lang/Class;");
jobject clsObj = env->CallObjectMethod(obj, mid);
// Now get the class object's class descriptor
cls = env->GetObjectClass(clsObj);
// Find the getName() method on the class object
mid = env->GetMethodID(cls, "getName", "()Ljava/lang/String;");
// Call the getName() to get a jstring object back
jstring strObj = (jstring)env->CallObjectMethod(clsObj, mid);
// Now get the c string from the java jstring object
const char* str = env->GetStringUTFChars(strObj, NULL);
// Print the class name
printf("\nCalling class is: %s\n", str);
// Release the memory pinned char array
env->ReleaseStringUTFChars(strObj, str);
Note that I haven't taken any actions to check for errors. This is just a small code snippet describing how it could be done.
Alternatively you could do this instead of using the GetStringUTFChars/ReleaseStringUTFChars
:
// Make sure that the buffer is large enough
char str[128];
jint strlen = env->GetStringUTFLength(strObj);
env->GetStringUTFRegion(strObj, 0, strlen, str);
printf("\nCalling class is: %s\n", str);
No need to release since the string is copied to local buffer.
In my case, I haven't had the object to get the class. Instead, I wanted to get the name of a given class, based on its signature.
So, this worked for me. I hope it can help:
// Find the class by its JNI signature
jclass cls = env->FindClass(expectedType);
// Get the class object's class descriptor
jclass clsClazz = env->GetObjectClass(cls);
// Find the getSimpleName() method in the class object
jmethodID methodId = env->GetMethodID(clsClazz, "getSimpleName", "()Ljava/lang/String;");
jstring className = (jstring) env->CallObjectMethod(cls, methodId);
// And finally, don't forget to release the JNI objects after usage!!!!
env->DeleteLocalRef(clsClazz);
env->DeleteLocalRef(cls);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With