Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I know the name of the class that calls a JNI C method?

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 ? .

like image 767
Y.E.P Avatar asked Oct 04 '12 03:10

Y.E.P


People also ask

How do I find the name of a 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.

Can we call a method using class name?

Yes, It is allowed to define a method with the same name as that of a class.

What is Jclass in JNI?

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 {}; ...

What is JNIEnv * env?

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.


2 Answers

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.

like image 104
maba Avatar answered Oct 20 '22 01:10

maba


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);
like image 26
Alexander Haroldo da Rocha Avatar answered Oct 20 '22 00:10

Alexander Haroldo da Rocha