这是与以前的帖子有关的问题,但是此帖子已解决,现在我想更改问题的方向。
当与工作JNI,有必要询问JNIEnv
对象jclass
和jmethodID
用于将在C / C
代码中使用每个类和方法。为了清楚起见,我想从C
/ C
调用Java构造函数或方法。
由于从Java到C / C ++的通信成本很高(反之亦然),因此我最初认为使这种情况最小化的一种方法是重用jclass
and
jmethodID
。因此,我将该实例保存在全局变量中,如下所示:
jclass someClass = NULL;
jmethodID someMethod = NULL;
JNIEXPORT jobject JNICALL Java_example_method1(JNIEnv *env, jobject jobj) {
// initialize someClass and someMethod if they are NULL
// use someClass and someMethod to call java (for example, thru NewObject)
}
JNIEXPORT jobject JNICALL Java_example_method2(JNIEnv *env, jobject jobj) {
// initialize someClass and someMethod if they are NULL
// use someClass and someMethod to call java again
}
一个更具体(且有用)的示例,我用它从JNI函数中的任何位置抛出异常:
jclass jniExceptionClass = NULL;
void throwJavaException(JNIEnv *env, const char* msg) {
if (!jniExceptionClass) {
jniExceptionClass = env->FindClass("example/JNIRuntimeException");
}
if (jniExceptionClass)
env->ThrowNew(jniExceptionClass, msg);
}
}
问题是我继续使用此 模式 并遇到了分段错误,只能通过不重复使用此变量来解决(这是上一篇文章的解决方案)。
问题是:
jclass
和jmethodID
通过不同的JNI函数是非法的?我认为这些价值观始终是相同的。jclass
和jmethodID
每个JNI功能的影响/开销是什么?这里的规则很明确。方法ID和字段ID的值是永远不变的。您可以挂在他们身上。查找需要一些时间。
jclass
另一方面,通常是 本地参考 。本地引用最多只能在一次调用JNI函数的过程中保留下来。
如果需要优化,则必须要求JVM为您提供全局引用。获取并保留对诸如的通用类的引用并不少见java.lang.String
。
当然,持有此类对类的引用将防止它(类)被垃圾回收。
jclass local = env->FindClass(CLS_JAVA_LANG_STRING);
_CHECK_JAVA_EXCEPTION(env);
java_lang_string_class = (jclass)env->NewGlobalRef(local);
_CHECK_JAVA_EXCEPTION(env);
env->DeleteLocalRef(local);
_CHECK_JAVA_EXCEPTION(env);
检查宏调用:
static inline void
check_java_exception(JNIEnv *env, int line)
{
UNUSED(line);
if(env->ExceptionOccurred()) {
#ifdef DEBUG
fprintf(stderr, "Java exception at rlpjni.cpp line %d\n", line);
env->ExceptionDescribe();
abort();
#endif
throw bt_rlpjni_java_is_upset();
}
}
我的老师让我这样做,但在评论区我被告知我不应该这样做。 为什么?
问题内容: 当我读一本Java书籍时,作者曾说过,在设计类时,与继承一起使用通常是不安全的。例如: 在上面的类中,我们应放置,以便其他类不能从此继承。我的问题是,为什么允许另一个类从中继承是不安全的? 问题答案: 因为很难(不可能?)做到正确,尤其是 对称 属性 。 说你有一堂课。产生如果参数也是并且具有相同的重量。如果要实现,则仅当参数也是汽车(重量除外)时,它才应屈服,并且还应比较制造商,发动
问题内容: 为什么不应该使用函数的技术原因是什么?(例如,或)? 为什么我要使用其他东西,即使它们在我的网站上工作? 如果它们在我的网站上不起作用,为什么我会收到类似的错误 警告:mysql_connect():没有那个文件或目录 问题答案: MySQL 扩展: 未在积极开发中 被正式弃用的PHP 5.5(发布2013年6月)。 自 PHP 7.0起 已完全删除 (2015 年 12 月发布) 这
问题内容: 想要改善这篇文章吗? 提供此问题的详细答案,包括引文和为什么答案正确的解释。答案不够详细的答案可能会被编辑或删除。 为什么不应该使用功能的技术原因是什么?(例如,或)? 即使我的网站上可以工作,我为什么还要使用其他东西? 如果它们在我的网站上不起作用,为什么会出现类似 警告:mysql_connect():没有这样的文件或目录 问题答案: MySQL扩展: 没有积极发展 被 正式 弃用
问题内容: 之间有什么区别: 和 我知道JPanel是GUI组件的容器,但我确实看不到使用它的实用程序。当然,我错了,但我是从Swing开始的,所以…为什么我应该使用JPanel?真正的目的是什么? 问题答案: 为什么我应该使用JPanel? 您可以使用JPanel获得以下一项或多项好处: 将组件分组在一起。 为了更好地组织您的组件。 为了使我们能够使用 多种布局 并组合其效果。(例如,用于数字键
问题内容: 一次又一次,我看到Bash在Stack Overflow上使用了答案,而答案被猛烈抨击了,旨在使用这种“邪恶的”构造。为什么这么邪恶? 如果不能安全使用,我应该怎么用呢? 问题答案: 这个问题比眼前的问题还重要。我们将从显而易见的内容开始:具有执行“脏”数据的潜力。脏数据是指尚未重写为XYZ的任何数据;在我们的例子中,它是未格式化的任何字符串,以确保评估安全。 乍看之下,对数据进行消毒