2010-10-24 12 views
5

Dato:Attivare enum in JNI?

enum Foo 
{ 
    FIRST, 
    SECOND 
} 

Qual è l'equivalente JNI per il seguente codice?

Foo foo = ...; 
int value; 
switch (foo) 
{ 
    case FIRST: 
    value = 1; 
    break; 
    case SECOND: 
    value = 2; 
    break; 
} 

So che posso usare foo.equals(Foo.FIRST) da JNI, ma mi piacerebbe per ottenere le stesse prestazioni di switch(enum). Qualche idea?

risposta

3

Si potrebbe avere una fase di processo che viene eseguita dopo la compilazione dell'enumerazione, ma prima che il codice JNI venga compilato. Caricherà l'enum e produrrà i valori in un file .h. Il tuo codice JNI quindi include questo file .h.

Edit:

Ecco un codice che fa questo. Ha bisogno di essere modificato per accettare argomenti e scrivere su un file invece di System.out, ma è abbastanza facile da fare.

URL u = new File("/home/adam/tmp").toURL(); 
    URLClassLoader loader = new URLClassLoader(new URL[] {u}, Test.class.getClassLoader()); 
    Class<? extends Enum> c = (Class<? extends Enum>) loader.loadClass("Color"); 
    PrintStream out = System.out; 
    out.println("#ifndef COLOR_H"); 
    out.println("#define COLOR_H"); 
    for(Enum constant : c.getEnumConstants()) { 
     out.println("#define " + c.getCanonicalName().replaceAll("\\.", "_") + "_" + constant.name() + " " + constant.ordinal()); 
    } 
    out.println("#endif"); 
+0

Ho implementato la tua proposta in Jace: https://sourceforge.net/projects/jace/ – Gili

+0

Contento di aver potuto aiutarti. –

+1

Non ne hai bisogno. Javah fa già esattamente questo. – EJP

1

cosa ti riferisci come value è in realtà l'ordinale del enum

Per ottenere un valore fetching, semplice negozio come un campo privato in voi FooEnum:

 
public enum FooEnum { 
    private final int value; 

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

    public int getValue() { 
     return value; 
    } 

    FIRST(1); 
} 

In questo modo è possibile passare in base al valore FooEnum.

+0

Perché FooEnum è stato dichiarato sopra come una classe piuttosto che come enum? –

+0

Per errore, l'ho scritto con enum vecchio stile – Bivas

1

È possibile utilizzare un'istruzione switch nel codice JNI pure, se:

  • fornire un campo di valore integrale nella classe enum Java.
  • Definire un insieme parallelo di costanti integrali in C o C++ (ad es. Con un'altra enumerazione).

La definizione ridondante introduce un rischio di divergenza. È possibile attenuarlo:

  • Documentando molto il parallelismo su entrambi i lati. Funziona meglio se l'enumerazione è piccola e cambia raramente.
  • Generazione del codice da una singola fonte.

Per esempio, in Java, si potrebbe avere:

public enum Foo { 
      FIRST(0), 
      SECOND(1); 

      public int getValue() { return m_value; } 

      private int m_value; 
      private Foo(int value) { m_value = value; } 
    } 

E in C++, si potrebbe avere:

enum Foo { 
      FIRST = 0, 
      SECOND = 1 
    }; 

Per un conteggio parallelo, io personalmente sempre fare i valori enum esplicito sul lato C/C++. Altrimenti, la cancellazione di un enumeratore su entrambi i lati può far divergere i valori.