如何从JNI设置Java枚举字段?

时间:2013-11-05 16:02:57

标签: java enums java-native-interface

如何从JNI 设置 Java枚举字段?这是示例代码。我想在本机函数“get_state”中设置我的B对象的“myState”字段。

public class A {

    public enum STATE { 
        STATE_ONE,
        STATE_TWO
    }

    public static class B {
        public STATE myState;
    }

    public native void get_state(B b);

    public B getB() {
        B b;

        // Call JNI to get the state
        get_state(b);

        return b;
    }
}


JNIEXPORT void JNICALL Java_A_get_1state(JNIEnv *env, jobject object, jobject b_object)
{
    /* Get a reference to obj's class */
    jclass cls = (*env)->GetObjectClass(env, b_object);

    //How do I set B object's "myState" field?

}

3 个答案:

答案 0 :(得分:4)

由于它是嵌套的枚举类,因此STATE是隐式静态的。有很多资源,但谷歌搜索可以在这里找到:http://www.javapractices.com/topic/TopicAction.do?Id=1

这允许在枚举类的valueOF methodID之上采用另一种方法。您可以使用env-> GetStaticField和env-> GetStaticObjectField来获取要设置的枚举。

例如:

jclass theStateClass = env->FindClass("your/containingPackage/A$STATE");
jfieldID stateOneField    = env->GetStaticFieldID(theStateClass, "STATE_ONE", "Lyour/containingPackage/A$STATE;");
jobject STATE_ONE = env->GetStaticObjectField(theStateClass, stateOneField);

答案 1 :(得分:0)

就像你只使用枚举名称时从Java那样做:

  1. 通过JNI查找类实例。
  2. 在枚举类
  3. 上调用valueOf(String)方法

答案 2 :(得分:0)

构建此类的Inolder,我做了一些小修改。

public class A {

    public enum STATE { 
        STATE_ONE,
        STATE_TWO
    }



    public native void get_state(B b);

    public B getB() {
        B b = new B();

        // Call JNI to get the state
        get_state(b);

        return b;
    }

    public static class B {
        public STATE myState = STATE.STATE_ONE;

    }
}

所以我们走了。 第一步是构建java类

javac A.java

所以我们得到了一个A.class文件。

第二,生成签名。

javap -v A

shell打印以下内容:

C:\Users\bowman\Desktop\project>javap -v -p -c A
Classfile /C:/Users/bowman/Desktop/project/A.class
  Last modified 2014-1-3; size 377 bytes
  MD5 checksum f331eddf740b0d8c256c851f04369088
  Compiled from "A.java"
public class A
  SourceFile: "A.java"
  InnerClasses:
       public static #7= #2 of #5; //B=class A$B of class A
       public static final #10= #9 of #5; //STATE=class A$STATE of class A
  minor version: 0
  major version: 51
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #6.#21         //  java/lang/Object."<init>":()V
   #2 = Class              #22            //  A$B
   #3 = Methodref          #2.#21         //  A$B."<init>":()V
   #4 = Methodref          #5.#23         //  A.get_state:(LA$B;)V
   #5 = Class              #24            //  A
   #6 = Class              #25            //  java/lang/Object
   #7 = Utf8               B
   #8 = Utf8               InnerClasses
   #9 = Class              #26            //  A$STATE
  #10 = Utf8               STATE
  #11 = Utf8               <init>
etc...

重点是:

  

公共类A

     

SourceFile:“A.java”

     

InnerClasses:

     

public static#7 =#5中的#2; // B = A类的A $ B

     

public static final#10 =#9中的#9; // STATE = A类的A $ STATE

所以我们可以假设enum是一个有“A $ STATE”签名的类

你可以通过以下方式在cpp中获得这个课程。

jclass A_State = env->FindClass( "LA$STATE;");
希望它有所帮助。