2010-10-24 32 views
5

dado:¿Enum enum en JNI?

enum Foo 
{ 
    FIRST, 
    SECOND 
} 

Cuál es el equivalente de JNI para el siguiente código?

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

Sé que puedo utilizar foo.equals(Foo.FIRST) de JNI, pero me gustaría conseguir el mismo rendimiento que switch(enum). ¿Algunas ideas?

Respuesta

3

Puede tener un paso de proceso que se ejecuta después de compilar la enumeración pero antes de compilar el código JNI. Cargaría la enumeración y daría salida a los valores a un archivo .h. Su código JNI incluye este archivo .h.

Editar:

Aquí hay un código que hace esto. Necesita ser modificado para aceptar argumentos y escribir en un archivo en lugar de System.out, pero eso es bastante fácil de hacer.

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

Implementé su propuesta en Jace: https://sourceforge.net/projects/jace/ – Gili

+0

Me alegro de poder ayudar. –

+1

No lo necesitas. Javah ya hace exactamente eso. – EJP

1

a qué se refiere como value es en realidad el ordinal de la enum

Para lograr un valor ir a buscar, almacenar sencilla como un campo privado en el que FooEnum:

 
public enum FooEnum { 
    private final int value; 

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

    public int getValue() { 
     return value; 
    } 

    FIRST(1); 
} 

esta manera se puede cambia según tu valor FooEnum.

+0

¿Por qué FooEnum se declaró anteriormente como una clase en lugar de una enumeración? –

+0

Por error, lo escribí con enum de estilo antiguo – Bivas

1

Se puede utilizar una sentencia switch en el código JNI así, si:

  • proporcionar un campo de valor integral en su clase de enumeración de Java.
  • Defina un conjunto paralelo de constantes integrales en C o C++ (por ejemplo, en otra enumeración).

La definición redundante presenta un riesgo de divergencia. Puede atenuar esto por:

  • Documentando a fondo el paralelismo en ambos lados. Esto funciona mejor si la enumeración es pequeña y cambia con poca frecuencia.
  • Generando el código desde una única fuente.

Por ejemplo, en Java, usted podría tener:

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

      public int getValue() { return m_value; } 

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

Y en C++, usted podría tener:

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

Para una enumeración paralelo, yo personalmente siempre que los valores de enumeración explícito en el lado C/C++. De lo contrario, una eliminación de un enumerador en ambos lados puede hacer que los valores diverjan.