如何使JNI FindClass返回的地址始终返回相同的地址 [英] How to make address returned by JNI FindClass return always the same address

查看:82
本文介绍了如何使JNI FindClass返回的地址始终返回相同的地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的C程序中,我有以下代码:

In my C program, I have the following code:

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中)并运行时,它会给出以下输出:

When I compile the program (in GCC) and run it, it gives the following output:

First: class=0x7f55ac089450 * method=0x7f55ac0d99b8

Second: class=0x7f55ac089458 * method=0x7f55ac0d99b8

如您所见,每次调用 FindClass 时,类的地址都不同.我认为该类的地址是静态的,并且在程序生命周期内不会更改.实际上,当您从IBM读到这篇有关如何使用JNI优化C代码的著名文章时( https://developer.ibm.com/languages/java/articles/j-jni/#notc ),他们说要缓存 FindClass 返回的值(因此人们希望它不会改变).但是,如果以后在JNI函数调用中使用此缓存的值,则会使C程序崩溃(因为它使用了错误的Java类地址).

As you can see, the address of the class is different each time FindClass is called. I thought the address of the class was static and it wouldn't change during the lifetime of our program. In fact, when one reads this well known article from IBM on how to optimize C code using JNI (https://developer.ibm.com/languages/java/articles/j-jni/#notc) they say to cache the value returned by FindClass (so one would expect that it doesn't change). But, if you later on use this cached value in a JNI function call, it will make your C program crash (as it is using a wrong address of the Java class).

另一个奇怪的事情是,当将 FindClass 返回的值缓存到 java/lang/Integer 类(而不是 java/lang/Short (如上文所述),然后稍后在所有工作正常且按预期方式运行(即没有崩溃)的情况下使用此缓存的值.

Another strange thing is that when caching the value returned by FindClass for the class java/lang/Integer (instead of java/lang/Short as posted above), and then use this cached value later on everything works correctly and as expected (i.e. no crash).

推荐答案

FindClass 返回的内容是

What FindClass returns is a local reference a Java Class object.

在您的示例中,您获得了两个单独的引用-但它们都可能引用同一个对象.

In your example, you get two separate references - but both of them may be referencing the same object.

考虑如果行为符合您的预期,并且您为两个 FindClass 调用获得了相同的引用,将会发生什么情况:

Consider what would happen if the behavior had been what you expected and you got the same reference for both FindClass calls:

first = (*env)->FindClass(env, "java/lang/Short");
second = (*env)->FindClass(env, "java/lang/Short");
(*env)->DeleteLocalRef(env, first);
method = (*env)->GetMethodID(env, second, "<init>", "(S)V");  // OOPS! this reference may no longer be valid

实际上,上述操作会很好,因为 first second 将分别引用 Class< Short> .

In actuality the above will work fine, because first and second will be separate references to Class<Short>.

这篇关于如何使JNI FindClass返回的地址始终返回相同的地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆