【发布时间】:2021-02-20 02:17:52
【问题描述】:
在我的 C 程序中,我有以下代码:
jclass class;
jmethodID method;
class = (*env)->FindClass(env, "java/lang/Short");
method = (*env)->GetMethodID(env, class, "<init>", "(S)V");
printf("First: class=%p * method=%p\n", class, method);
class = (*env)->FindClass(env, "java/lang/Short");
method = (*env)->GetMethodID(env, class, "<init>", "(S)V");
printf("Second: class=%p * method=%p\n", class, method);
当我编译程序(在 GCC 中)并运行它时,它会给出以下输出:
First: class=0x7f55ac089450 * method=0x7f55ac0d99b8
Second: class=0x7f55ac089458 * method=0x7f55ac0d99b8
如您所见,每次调用FindClass 时,类的地址都是不同的。我认为类的地址是静态的,并且在我们程序的生命周期内不会改变。事实上,当人们阅读 IBM 的这篇关于如何使用 JNI (https://developer.ibm.com/languages/java/articles/j-jni/#notc) 优化 C 代码的著名文章时,他们说要缓存 FindClass 返回的值(所以人们会认为它不会改变)。但是,如果你稍后在 JNI 函数调用中使用这个缓存值,它会使你的 C 程序崩溃(因为它使用了错误的 Java 类地址)。
另一个奇怪的事情是,当缓存 FindClass 为类 java/lang/Integer 返回的值时(而不是上面发布的 java/lang/Short),然后稍后使用这个缓存的值,一切正常并按预期工作(即没有崩溃)。
【问题讨论】:
-
什么保证你拨打
FindClass时地址是一样的?除非short-我的意思是int-的直接值相同,否则我不会期望这一点。
标签: java c java-native-interface