Weird: can not change the value of Integer in jni(奇怪:不能改变jni中Integer的值)
问题描述
I write a jni function to set the value of two java Integer object in C, just like this:
jni_do_something(JNIEnv *env, jobject thiz, jobject p1, jobject p2) {
jclass c;
jfieldID id;
c = env->FindClass("java/lang/Integer");
if (c==NULL)
{
LOGD("FindClass failed");
return -1;
}
id = env->GetFieldID(c, "value", "I");
if (id==NULL)
{
LOGD("GetFiledID failed");
return -1;
}
env->SetIntField(p1, id, 5);
env->SetIntField(p2, id, 10);
return 0;
}
In java, I called this function:
native int do_something(Integer p1, Integer p2);
Integer p1=0, p2=0;
do_something(p1, p2);
Log.d("test", "p1: "+p1);
Log.d("test", "p2: "+p2);
The output are both '10', why?
===============================================
I have done many tests, and got the following points. (Answer, comments are welcome)
I don't think this jni native is unable to alter immutable object. After all, the both objects are changed to 10 from 0.
There is some relation to auto-boxing (yes? I'm not sure). Maybe p1 and p2 are specially processed by jvm, made pointed to a single object if initialized with:
Integer p1=0, p2=0;
If change to:
Integer p1=0, p2=1;
or
Integer p1 = new Integer(0);
Integer p2 = new Integer(0);
The result is right (p1:5, p2:10). Can anyone clarify this?
Maybe what I said is not correct. I have write the following code in java:
Integer a = 0;
Integer b = 0;
b = 10;
Log.d("test", "a: "+a);
Log.d("test", "b: "+b);
It output 0, 10. So, they point to not a single object. I'm really confused.
Integer i1 = 500, i2 = 10000;
testInts(i1, i2);
Log.d("log", "I1 = " + i1);
Log.d("log", "I2 = " + i2);
or
Integer i1 = new Integer(0), i2 = new Integer(0);
testInts(i1, i2);
Log.d("log", "I1 = " + i1);
Log.d("log", "I2 = " + i2);
output
I1 = 10
I2 = 10
I1 = 5
I2 = 10
I1 = 5
I2 = 10
Works (first result using your example). I have remembered something that if value is in byte (or?) range then java uses some weird optimization. EDIT: appears it is a rule for autoboxing for small values.
c code
jclass clazz = (*env)->GetObjectClass(env, i1);
jfieldID mi = (*env)->GetFieldID(env, clazz, "value", "I");
(*env)->SetIntField(env, i1, mi, 5);
(*env)->SetIntField(env, i2, mi, 10);
return 0;
这篇关于奇怪:不能改变jni中Integer的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:奇怪:不能改变jni中Integer的值
基础教程推荐
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01