So, this is an edge case that no amount of Googling seems to unearth.
I have an enum in Kotlin;
package myapp
public enum State {
STATE_SUCCEEDED,
STATE_FROZEN,
STATE_WAITING,
STATE_IN_PROGRESS,
STATE_FAILED
}
I then have an object that contains this enum as a value in a member variable
package myapp
class AppState (
val state: State
)
Then, in C, I want to create an instance of AppState
jclass cls = (*env)->FindClass(env, AppState_ClassPath);
if (cls == NULL) {
__android_log_print(ANDROID_LOG_INFO, "DEBUG", "AppState class is null");
}
jmethodID mid = (*env)->GetMethodID(env, cls, "<init>", "(Lmyapp/State;)V");
return (*env)->NewObject(
env,
cls,
mid,
enumState
);
Now, when the C code is called from Kotlin, I get the error
JNI DETECTED ERROR IN APPLICATION: JNI NewStringUTF called with pending exception java.lang.NoSuchMethodError: no non-static method "Lmyapp/AppState;.<init>(Lmyapp/State;)V"
I understand why I get this error, since Enums have no public constructor, but not sure of the workaround. How should this enum be added to the signature?
Many thanks!
EDIT: (output from javap)
public final class myapp.AppState {
public myapp.AppState(myapp.State);
descriptor: (Lmyapp/State;)V
public final myapp.State getState();
descriptor: ()Lmyapp/State;
}
EDIT 2: (enum conversion function)
jobject
getState(JNIEnv* env, enum State state) {
char path[64];
char* stateName;
switch(state) {
case STATE_SUCCEEDED:
stateName = "STATE_SUCCEEDED";
break;
case STATE_FROZEN:
stateName = "STATE_FROZEN";
break;
case STATE_WAITING:
stateName = "STATE_WAITING";
break;
case STATE_IN_PROGRESS:
stateName = "STATE_IN_PROGRESS";
break;
default:
stateName = "STATE_FAILED";
};
snprintf(path, sizeof(path) - 1,"[L%s;", State_ClassPath);
jclass cls = (*env)->FindClass(env, State_ClassPath);
jfieldID fid = (*env)->GetStaticFieldID(env, cls , stateName, path);
jobject stateObj = (*env)->GetStaticObjectField(env, cls, fid);
return stateObj;
}
The answer turned out to be an erroneous [
in the code. Using javap -s
and copying / pasting from the output is the safest way to avoid this issue.