Let’s assume we have got the following simple enum:
package test;
public enum MyEnum {
VALUE1, VALUE2, VALUE3;
}
Since Java version 1.5 enums are converted to ordinary Java classes so treat them is similar to any other Java object (I recommend you to decompile compiled MyEnum.class file). For the following native method declaration:
package test;
public class SomeClass {
public native String enumTest(MyEnum myEnum);
}
is then, using javah generator (it’s part of JDK, not just JRE), generated following C header:
JNIEXPORT jstring JNICALL Java_test_SomeClass_ enumTest(JNIEnv *, jobject, jobject);The first parameter is pointer to Java environment, second is Java the object on which is the native method called and the third is the myEnum parameter (notice that the type is object). The way how to handle object in native code is a little bit similar to the Java reflections.
The first thing you have to do is to find the name of the method that returns actual "value" of the enum. You can find in the documentation (http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Enum.html) that every enum has (among others) method name() that returns name of the value of the enum as String (the second usable method is ordinal() ). Now I’m going to show you how to call the name() method in native code implemented using C++:
JNIEXPORT jstring JNICALL Java_test_SomeClass_ enumTest(JNIEnv *env, jobject obj, jobject enumObj) {On the first line the pointer to the class is obtained using FindClass (http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/functions.html#wp16027) method. You should notice that package name is delimited by "/" and not by ".". On the second line the pointer to the correct method - name() is obtained using GetMethodID (http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/functions.html#wp16660) method. You have to provide correct method’s signature (look into the specification how to get correct method’s signature). The third line calls the method against given object. CallObjectMethod (http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/functions.html#wp4256) means that the method itself returns object (String). The fourth line converts returned string value from UTF-8 (which is used as encoding of strings in Java) to C encoding and finally the last line just compares obtained valued against one of the enum’s values.
jclass enumClass = env->FindClass("test/MyEnum");
jmethodID getNameMethod = env->GetMethodID(enumClass, "name", "()Ljava/lang/String;");
jstring value = (jstring)env->CallObjectMethod(enumObj, getNameMethod);
const char* valueNative = env->GetStringUTFChars(value, 0);
if (strcmp(valueNative, "VALUE1") == 0) {
printf("Enum has the VALUE1 value");
}
// ...
return NULL;
}
4 comments:
Hi,
thank's for the great blog - exactly what I needed!
Reards,
Volker Simonis
hi, can you give Enum.valueOf jni method example?
Thanks!
i want to use ArrayList in java code but i dont know how to use side of jni of code.ihave class that is called ObjectClass and i declared this variable ArrayList pValue.how to use and reach entities of pValue.please help me
Enum turns out to be very versatile than the standard fixed input variable. Enum can also be used in reverse lookup and can be more descriptive with custom toString implementation. here is good link of various examples of enum in java
Post a Comment