You're lucky Java and Android use the Unicode character set. However, Android (by default) uses UTF-8 encoding, which JNI does not support internally. However, Java classes are fully capable of converting character set encodings. The constructors lang.java.String allow you to specify a character set / encoding or use OS-default, which on Android, of course, is encoded as UTF-8.
To simplify (I prefer coding in Java, minimizing the code that calls the JNI library), create an overload of your method and do some implementation in Java:
private static byte[] getLevelFile(byte[] levelName) { return getLevelFile(new String(levelName)).getBytes(); }
Now the JNI code should only deal with jbytearray, both for the parameter and for the return value:
JniMethodInfoJavaApi methodInfo; if (! getStaticMethodInfo(methodInfo, "getLevelFile", "([B)[B")) { return std::string(""); } LOGD("calling getLevelFile"); int nameLength = levelName.length(); jbyteArray nameBytes = methodInfo.env->NewByteArray(nameLength); methodInfo.env->SetByteArrayRegion(nameBytes, 0, nameLength, reinterpret_cast<const jbyte*>(levelName.c_str())); jbyteArray returnString = (jbyteArray) methodInfo.env->CallStaticObjectMethod(methodInfo.classID, methodInfo.methodID, nameBytes); LOGD("returned from getLevelFile"); methodInfo.env->DeleteLocalRef(methodInfo.classID); methodInfo.env->DeleteLocalRef(nameBytes); int returnLength = methodInfo.env->GetArrayLength(returnString); std::string data; data.reserve(returnLength); methodInfo.env->GetByteArrayRegion(returnString, 0, returnLength, reinterpret_cast<jbyte*>(&data[0])); methodInfo.env->DeleteLocalRef(returnString); LOGD("returning Level data"); return data;
source share