Passing pointer from C to Java becomes NULL(将指针从 C 传递到 Java 变为 NULL)
问题描述
I'm working on an Android app for x86 that requires some integration with C. I've been using swig/JNI to do the trick, and things have been running smoothly for the most part. However, pointers have been giving me some errors.
My issue is that I am able to successfully reference variable addresses in the emulator (ARM) but on a device (x86), things do not go as well.
Using the example from this link, I discovered that the address of any allocated variable in C becomes NULL once this address passes over to Java. For example...
Swig-generated JNI:
SWIGEXPORT jlong JNICALL Java_exampleJNI_new_1intp(JNIEnv *jenv, jclass jcls) {
jlong jresult = 0 ;
int *result = 0 ;
(void)jenv;
(void)jcls;
result = (int *)new_intp();
LOGI("Result is %x", result);
*(int **)&jresult = result;
LOGI("JResult is %x", jresult);
return jresult;
}
Source file containing new_intp():
static int *new_intp() {
return (int *) calloc(1,sizeof(int));
}
I have print statements checking the value of the address as it originates in C and passes over to Java. In new_intp(), the new variable is allocated a good looking address, but once this value returns to JNI and gets cast as a jlong, it turns to NULL.
In other words, *(int **)&jresult = result;
causes jresult to be 0.
Why does this happen? Is there some particularity of x86 that disallows JNI to work with pointers? Or is it because I'm testing it on a physical device rather than an emulator?
Regards
It looks to me like it could be an endianness issue.
*(int **)&jresult = result;
If int
is 32 bits, and jresult
is 64 bits, then on a big-endian architecture this could give unexpected results.
&jresult
is a pointer to a 64-bit value, so if you cast it to a pointer to a 32-bit value, then you're pointing at the lower-addressed of the two constituent 32-bit words. In a big-endian system this will be the most significant word. So after writing a 32-bit word to the most significant end of the 64-bit value, you get a 64-bit value which is 2^32 times bigger than what you expect.
If your LOGI
call is treating the parameter as a 32-bit int, and implicitly down-casting it from a 64-bit value, then it will give 0.
Can you see if this works instead?
jresult = (jlong) result;
这篇关于将指针从 C 传递到 Java 变为 NULL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:将指针从 C 传递到 Java 变为 NULL
基础教程推荐
- 如何强制对超级方法进行多态调用? 2022-01-01
- Java 中保存最后 N 个元素的大小受限队列 2022-01-01
- 如何在不安装整个 WTP 包的情况下将 Tomcat 8 添加到 Eclipse Kepler 2022-01-01
- 由于对所需库 rt.jar 的限制,对类的访问限制? 2022-01-01
- 如何对 HashSet 进行排序? 2022-01-01
- 在螺旋中写一个字符串 2022-01-01
- 首次使用 Hadoop,MapReduce Job 不运行 Reduce Phase 2022-01-01
- 如何使用 Eclipse 检查调试符号状态? 2022-01-01
- Spring Boot Freemarker从2.2.0升级失败 2022-01-01
- 如何使用 Stream 在集合中拆分奇数和偶数以及两者的总和 2022-01-01