4

I am importing headers from an existing project for a port to Android-NDK. In a few cases, there are enums defined in the native headers which I would like to use from the Java layer. How can one go about doing that?

Ideally, I'd like to just expose the constants to the Java layer somehow, but I don't see a way to do that.

The most obvious possibility is to doubly-define the enums in both Java and C++. However, the existing headers a) have no explicit numbering, b) have elements which are #ifdef'ed, and c) are shared with existing projects through SVN Externals. Therefore, doubly-defining the enums seems substantially more brittle than even the typical case.

The next idea is to use some build-time code-gen to create the enum in Java based on the pre-processed header -- possibly just as integer constants rather than a Java enum?

The third and most-nebulous idea I have is to define the enum in Java, pass those objects to the JNI glue, and have it compare against the some invocation of FindClass(), GetStaticFieldID(), and GetStaticObjectField(); then have the JNI glue re-map those to the native enum. That all seems inefficient, though.

Suggestions?

benkc
  • 3,292
  • 1
  • 28
  • 37
  • And, a stack exchange etiquette question: if I have a question and a few known possible answers (but hopes for something even better), like this one, would it be preferred to split my potential-answers out into multiple actual "Answers" for voting/discussion? Or does that just come across as egregious rep-farming? – benkc Nov 20 '12 at 22:12
  • Everybody else seems to do what you've done above. – user207421 Nov 20 '12 at 22:37
  • The questions about Stack Overflow itself belong to http://meta.stackoverflow.com. – Jakub Zaverka Nov 20 '12 at 23:04

1 Answers1

1

I would make a completely independent set of Java enums, and map between them at the JNI level where you have both available. Make sure to run javah on the enum classes so you get some #defines for their ordinals.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • 1
    A few tips for anyone who comes upon this later: 1) To run javah on a class com.example.Foo, you should have already built classes/com/example/Foo.class, then run: `javah -classpath path/to/classes com.example.Foo` 2) AFAICT, javah does not create anything for Java enums within the specified class. Instead declare a bunch of `public static final int MY_ENUM_ITEM_A = 1`, etc. These will be turned into #defines of the form `#define com_example_Foo_MY_ENUM_ITEM_A 1L` – benkc Nov 21 '12 at 01:12
  • 1
    @benkc `javah` should create #defines for the ordinals of the enum classes. You might have to specify their complete names directly to `javah`. I have definitely done this so it does work. – user207421 Nov 21 '12 at 01:24
  • 2
    @EJP was this you issuing a correction to this statement on another forum? https://forums.oracle.com/message/9750197#9750197 If so, javah doesn't create #defines for ordinals of enums, just for public static final ints. – Eliot Nov 18 '13 at 22:18