如何修复 env->NewObject() 上的 JNI 崩溃?
Posted
技术标签:
【中文标题】如何修复 env->NewObject() 上的 JNI 崩溃?【英文标题】:How to fix JNI crash on env->NewObject()? 【发布时间】:2014-12-22 02:06:10 【问题描述】:这是我的程序:
extern "C"
JNIEXPORT jint Java_android_app_integrity_VerifyIntegrity_checkCrc(JNIEnv *jniEnv,jobject thiz,jstring crcStr)
jclass clsZipFile = jniEnv->FindClass("java/util/zip/ZipFile");
jmethodID mtdConstruct = jniEnv->GetMethodID(clsZipFile, "<init>", "(Ljava/lang/String;)V");
jmethodID mtdGetEntry = jniEnv->GetMethodID(clsZipFile,"getEntry","(Ljava/lang/String;)Ljava/util/zip/ZipEntry;");
jclass clsZipEntry = jniEnv->FindClass("java/util/zip/ZipEntry");
jmethodID mtdGetCrc = jniEnv->GetMethodID(clsZipEntry,"getCrc","()L");
LOGD("pos2");
jobject objZipFile = jniEnv->NewObject(clsZipFile,mtdConstruct,crcStr);
if (NULL == objZipFile)
LOGD("NULL == objZipFile");
LOGD("pos3");
jobject objZipEntry = jniEnv->CallObjectMethod(objZipFile, mtdGetEntry,"classes.dex");
LOGD("pos4");
jlong ret = jniEnv->CallLongMethod(objZipEntry, mtdGetCrc);
LOGD("%ld",(long int)ret);
return 0;
;
它只打印“pos2”。 "LOGD("pos2");" 下面的行会导致崩溃! 我找不到原因。谁能帮我?谢谢!
【问题讨论】:
只是好奇——你为什么要这样做?您将一个 java 字符串向下传递给 C,然后仅使用它来创建一个 java 对象——只需在 java 端执行此操作并传递 jobject 以避免一些 JNI 痛苦。事实上,根本没有充分的理由在 C 中完成任何这些工作。你甚至不会得到速度提升。 您需要更多的错误检查。您调用的每个 JNI API 都可能静默失败。显然,类查找或构造函数查找失败。你为什么要在 JNI 中编码呢?就是一行 Java 代码。 【参考方案1】:尝试修复以下行。它的签名无效,会导致 MethodNotFound 异常抛出隐式异常,这很可能是罪魁祸首。
jmethodID mtdGetCrc = jniEnv->GetMethodID(clsZipEntry,"getCrc","()L");
应该是:
jmethodID mtdGetCrc = jniEnv->GetMethodID(clsZipEntry,"getCrc","()J");
但是,我会提出其他建议来检查所有 FindClass 和 FindMethod 调用的返回值,因为它们不仅返回 NULL,而且每个在失败时都会抛出异常。当 JNI 无法分配本地引用对象以返回您的 jclass 查找时,还会引发 OutOfMemoryException。
【讨论】:
以上是关于如何修复 env->NewObject() 上的 JNI 崩溃?的主要内容,如果未能解决你的问题,请参考以下文章
如何修复 Heroku 上的 ActionDispatch::Cookies::CookieOverflow 错误?
如何修复未在 centos 中的 smtp mailtrap.io 上建立的连接
(sass):26096 如何修复 Rails 中的“Sass::SyntaxError: Invalid CSS after”错误