【问题标题】:Object creation in JNIJNI 中的对象创建
【发布时间】:2014-08-11 16:20:47
【问题描述】:

我有一个类和一个枚举,如下所示:

public class ppmerrJNI 
{
   public enum ppm_err_e {
        ONE(0),
        TWO(1),
        THREE(2);

         private int code;

         private ppm_err_e(int code) {
           this.code = code;
         }

         public int getValue() {
           return code;
         }

        ppm_err_e getObj(int i) {
            return ppm_err_e.values()[i];
        }
    };
...
}

我有这样声明的 JNI 包装函数:

JNIEXPORT jobject JNICALL Java_ppmerrJNI_ppm_1get_1last_1error(JNIEnv *env, jobject thisObj) {
       int someNumber = 5;

       jclass employeeClass = (*env)->FindClass(env,"ppmerrJNI$ppm_err_e");
       jmethodID midConstructor = (*env)->GetMethodID(env, employeeClass, "<init>", "(I)V");
       jobject employeeObject = (*env)->NewObject(env, employeeClass, midConstructor, someNumber);
       return employeeObject ;
}

在第二行 (GetMethodId) 我得到:“线程中的异常”main“java.lang.NoSuchMethodError:”。

基本上,我想调用枚举类型“ppm_err_e”的构造函数,它位于类“ppmerrJNI”中。我想根据 someNumber 返回一个枚举对象,这是我采用的方法;也可以满足于任何其他可能的解决方案。

我也试过:

jmethodID constructor = (*env)->GetMethodID(env, enumClass, "getObj", "(I)LppmerrJNI$ppm_err_e;");

但它总是返回 null。

提前谢谢你!

【问题讨论】:

  • 您是否确认这些名称是您班级的实际名称? "ppmerrJNI$ppm_err_e"?你不检查FindClass是否成功。
  • 确保employeeClass 不是NULL
  • 是的,我已经检查过了,它不为空。
  • 会不会因为枚举有私有构造函数而不能调用枚举的构造函数?
  • 是的,好像是这样:stackoverflow.com/questions/9614282/…

标签: java c++ enums java-native-interface wrapper


【解决方案1】:

你不能实例化枚举。这就是为什么我不能调用 JNI 的 NewObject() 方法的原因(枚举只允许私有构造函数,因此无法实例化 - 你需要公共构造函数)。我通过在外部类中创建一个方法来解决它,该方法将枚举索引作为参数并返回相应的枚举实例。该方法在 JNI 中通过 CallObjectMethod() 而不是 NewObject() 调用。

【讨论】:

    【解决方案2】:

    尝试以下方法。您应该访问静态字段,而不是构造枚举。

    JNIEXPORT jobject JNICALL Java_ppmerrJNI_ppm_1get_1last_1error(JNIEnv *env, jobject thisObj) {
           int someNumber = 5;
    
           jclass employeeClass   = (*env)->FindClass(env, "ppmerrJNI");
           jfieldID oneField = (*env)->GetStaticFieldID(env, employeeClass , "ONE", "ppmerrJNI$ppm_err_e;");
           jobject STATE_ONE      = (*env)->GetStaticObjectField(env, employeeClass, oneField);
    
           return employeeObject ;
    }
    

    【讨论】:

    • 我知道如何通过 ist 名称/字符串获取枚举值,但我需要通过数字 (someNumber) 获取它...
    猜你喜欢
    • 2011-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-17
    • 2020-02-11
    相关资源
    最近更新 更多