2023-01-20 300
我正在为X86的Android应用程序工作,该应用需要与C进行一些集成.我一直在使用Swig/Jni来实现这一问题,并且大部分情况下运行顺利.但是,指针一直给我一些错误.
我的问题是,我能够在模拟器(ARM)中成功引用变量地址,但是在设备(x86)上,事情也没有进行.
使用该示例来自此链接,我发现C中任何分配变量的地址一旦该地址传递给Java,C中的任何分配变量就会无效.例如…
swig生成的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;
}
包含new_intp()的源文件:
static int *new_intp() {
return (int *) calloc(1,sizeof(int));
}
我有打印语句检查地址的源于C的值,并传递给Java.在new_intp()中,新变量分配了一个好看的地址,但是一旦此值返回JNI并将其施放为jlong,它将变为null.
换句话说,*(int **)&jresult = result;使Jresult为0.
为什么会发生这种情况? X86是否有某种特殊性使JNI与指针合作?还是因为我在物理设备而不是模拟器上测试它?
问候
在我看来,这可能是一个终点问题.
*(int **)&jresult = result;
如果int为32位,而jresult为64位,那么在大型体系结构上,这可能会带来意外的结果.
&jresult是一个指向64位值的指针,因此,如果将其投入到32位值的指针中,那么您指向两个组成型32位单词的下降.在大型系统中,这将是最重要的词.因此,在将32位单词写成64位值的最重要端口之后,您将获得64位值,比您期望的大2^32倍.
如果您的LOGI呼叫将参数视为32位int,并隐式将其从64位值降低,则将给出0.
您可以看到这是否有效吗?
jresult = (jlong) result;
实际上,这是 pointer-aliasiasing 问题. Swig使用的是老式的C指针技术,在优化开始时,该技术在新的海湾合作室中不起作用.埋葬在swig文档中,特别是说什么? p>
重要
如果您要使用GCC打开优化
(例如-O2),请确保您还使用-fno -strict -coliasing编译.
从GCC-4.0开始,海湾合作委员会的优化变得更加积极
并将导致在严格的别名优化的情况下失败的代码
打开.请参阅 c/c/c/c ++ c/c ++ to Java tos to Java tos to Java tosemaps e节
详细信息./p>
以上所述是小编给大家介绍的将指针从C到Java变为无效,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!
原文链接:https://77isp.com/post/26069.html
=========================================
https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。
数据库技术 2022-03-28
网站技术 2022-11-26
网站技术 2023-01-07
网站技术 2022-11-17
Windows相关 2022-02-23
网站技术 2023-01-14
Windows相关 2022-02-16
Windows相关 2022-02-16
Linux相关 2022-02-27
数据库技术 2022-02-20
抠敌 2023年10月23日
嚼餐 2023年10月23日
男忌 2023年10月22日
瓮仆 2023年10月22日
簿偌 2023年10月22日
扫码二维码
获取最新动态