2010-10-24 16 views
5

Gegeben:Enumeration in JNI einschalten?

enum Foo 
{ 
    FIRST, 
    SECOND 
} 

Was die JNI Äquivalent für den folgenden Code ist?

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

Ich weiß, ich foo.equals(Foo.FIRST) von JNI verwenden können, aber ich möchte die gleiche Leistung wie switch(enum) bekommen. Irgendwelche Ideen?

Antwort

3

Sie könnten einen Prozessschritt ausführen, der nach dem Kompilieren der Enumeration, aber vor dem Kompilieren des JNI-Codes ausgeführt wird. Es würde die Enumeration laden und die Werte in eine .h-Datei ausgeben. Ihr JNI-Code enthält dann diese .h-Datei.

Edit:

Hier einige Code, der dies tut. Es muss geändert werden, um Argumente zu akzeptieren und in eine Datei statt in System.out zu schreiben, aber das ist einfach genug.

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

Ich habe Ihren Vorschlag in Jace implementiert: https://sourceforge.net/projects/jace/ – Gili

+0

Ich bin froh, dass ich helfen konnte. –

+1

Sie brauchen es nicht. Javah macht genau das schon. – EJP

1

Was Sie sich beziehen, wie value ist eigentlich die Ordnungs der enum

Um Wert fetching, einfach speichern es als privates Feld in Sie zu erreichen FooEnum:

 
public enum FooEnum { 
    private final int value; 

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

    public int getValue() { 
     return value; 
    } 

    FIRST(1); 
} 

Auf diese Weise können Sie Schalten Sie basierend auf Ihrem FooEnum Wert.

+0

Warum wird FooEnum oben als Klasse und nicht als Enum deklariert? –

+0

Aus Versehen habe ich es mit alten Enum geschrieben – Bivas

1

Sie können auch eine switch-Anweisung in Ihrem JNI-Code verwenden, wenn Sie:

  • ein Integralwert-Feld in Ihrer Java Enum-Klasse sorgen.
  • Definieren Sie eine parallele Menge von Integralkonstanten in C oder C++ (z. B. durch eine andere Enumeration).

Die redundante Definition führt zu einem Divergenzrisiko. Sie können dies mildern durch:

  • Schwer dokumentiert die Parallelität auf beiden Seiten. Dies funktioniert am besten, wenn die Aufzählung klein ist und sich selten ändert.
  • Generieren des Codes aus einer einzigen Quelle.

Zum Beispiel in Java, könnten Sie haben:

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

      public int getValue() { return m_value; } 

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

Und in C++, könnten Sie haben:

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

Für eine parallele Zählung mache ich persönlich immer die ENUM-Werte explizit auf der C/C++ Seite. Andernfalls kann ein Löschen eines Enumerators auf beiden Seiten dazu führen, dass die Werte abweichen.