2013-08-06 2 views
3

У меня есть приложение Java и JNI (dll). Я хочу знать, как получить значение enum (int), которое передается как параметр JNI.Как получить значение перечисления, передаваемого JNI

Вот перечисление (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

Вы должны предоставить метод для возврата значения 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 
} 
+0

Можете ли вы показать мне, как, давая пример кода? – BebzSusuma

+0

Я через минуту, после того, как узнаю о JNI. (Просто шучу, я немного об этом знаю.) – tbodt

+0

На самом деле, нет необходимости добавлять метод. Нативная функция также может быть «GetFieldID()» для поля _private_ «значение» и использовать «GetIntField()» для анализа значения с помощью той же логики коммутатора. –

4

Я не был в состоянии использовать решение, предоставленную @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 
} 
+0

Это реальный ответ, так как он не требует изменения перечисления. – Leandros

+0

Спасибо, хотя я, вероятно, просто передам значение ordinal() функции JNI, которая принимает int. Кажется, для меня чище. –

2

На самом деле, вместо определения getValue() метода можно назвать Enum.ordinal().

Более простое решение немного изменить код C и использовать Enum.ordinal() непосредственно при вызове функции JNI, т.е. передать 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

Смежные вопросы