我正在尝试在Android中调用以下java方法
public static String getLevelFile(String levelName) { /*body*/}
从 C++ 使用以下 jni 代码
JniMethodInfoJavaApi methodInfo;
if (! getStaticMethodInfo(methodInfo, "getLevelFile", "(Ljava/lang/String;)Ljava/lang/String;"))
{
return std::string("");
}
LOGD("calling getLevelFile");
jstring returnString = (jstring) methodInfo.env->CallStaticObjectMethod(methodInfo.classID, methodInfo.methodID, levelName.c_str());
LOGD("returned from getLevelFile");
methodInfo.env->DeleteLocalRef(methodInfo.classID);
const char *js = methodInfo.env->GetStringUTFChars(returnString, NULL);
std::string cs(js);
methodInfo.env->ReleaseStringUTFChars(returnString, js);
LOGD("returning Level data");
执行以下操作时应用程序崩溃CallStaticMethodObject()
。我已经通过使用验证方法签名是正确的javap
。还有LOGD("calling getLevelFile");
打印得很好,然后就崩溃了。我能做其他的事CallStaticVoidMethod()
来自同一个班级,但不是这个班级。有什么想法我做错了吗?
你很幸运,Java 和 Android 都使用 Unicode 字符集。但是,Android(默认情况下)使用 UTF-8 编码,而 JNI 本质上并不支持该编码。尽管如此,Java 类完全能够在字符集编码之间进行转换。这lang.java.String
构造函数允许您指定字符集/编码或使用操作系统默认值,当然,在 Android 上编码为 UTF-8。
为了使它更容易(我更喜欢用 Java 编码,尽量减少调用 JNI 库的代码),创建方法的重载并用 Java 执行一些实现:
private static byte[] getLevelFile(byte[] levelName) {
return getLevelFile(new String(levelName)).getBytes();
}
现在 JNI 代码只需要处理 jbytearray,无论是参数还是返回值:
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;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)