有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何获取传递给JNI的枚举值

我有一个Java应用程序和JNI(dll)。我想知道如何获取作为参数传递给JNI的枚举(int)的值

以下是枚举(Java):

public enum envelopeType
{
    NOT_SPECIFIED(-1),
    NONE(0),
    IMAGE(1),
    BITMAP(2);

    private int value;

    private envelopeType(int value)
    {
        this.value = value;
    }   
}

以下是JNI代码(C++):

JNIEXPORT jint JNICALL Java_Loader_Convert
  (JNIEnv *env, jobject obj, jobject EnvelopeType)

既然枚举是作为对象传递的,我怎么能得到它的值呢


共 (3) 个答案

  1. # 1 楼答案

    我无法使用@tbodt提供的解决方案,但他的解决方案离我很近,我能够找到解决方案

    查看java enum documentaiton有一个方法ordinal,它将以int类型返回枚举值

    我使用的代码与@tbodts解决方案中的代码几乎相同,但是传递到GetMethodID函数中的字符串是不同的。我不需要创建getValue方法,方法签名是()I而不是I()

    JNIEXPORT jint JNICALL Java_Loader_Convert(JNIEnv *env, jobject obj, jobject EnvelopeType) {
        jmethodID envelopeGetValueMethod = (*env)->GetMethodID(env, (*env)->FindClass(env, "package/of/envelopeType"), "ordinal", "()I");
        jint value = (*env)->CallIntMethod(env, EnvelopeType, envelopeGetValueMethod);
        switch (value) {
            case -1:
            // not specified
            break;
            case 0:
            // none
            break;
            ...
        }
        // rest of native method
    }
    
  2. # 2 楼答案

    实际上,您可以调用Enum.ordinal(),而不是定义getValue()方法

    一个更简单的解决方案是稍微修改C代码,在调用JNI函数时直接使用Enum.ordinal(),即传递一个jint而不是Enum对象:

    JNIEXPORT jint JNICALL Java_Loader_convert
      (JNIEnv *env, jobject obj, jint EnvelopeType)
    

    在Java中,你得到了一种

    loader.convert(myEnvelopeType.ordinal());
    

    http://docs.oracle.com/javase/7/docs/api/java/lang/Enum.html#ordinal%28%29

  3. # 3 楼答案

    您将提供一个方法来返回value的值,然后从本机代码调用该值并使用switch语句。以下是枚举中的方法:

    public int getValue() {
        return value;
    }
    

    以及您的本地方法:

    JNIEXPORT jint JNICALL Java_Loader_Convert(JNIEnv *env, jobject obj, jobject EnvelopeType) {
        jmethodID envelopeGetValueMethod = (*env)->GetMethodID(env, (*env)->FindClass(env, "package/of/envelopeType"), "getValue", "()I");
        jint value = (*env)->CallIntMethod(env, EnvelopeType, envelopeGetValueMethod);
        switch (value) {
            case -1:
            // not specified
            break;
            case 0:
            // none
            break;
            ...
        }
        // rest of native method
    }