将指针从C到Java变为无效

 2023-01-20    300  

问题描述

我正在为X86的Android应用程序工作,该应用需要与C进行一些集成.我一直在使用Swig/Jni来实现这一问题,并且大部分情况下运行顺利.但是,指针一直给我一些错误.

我的问题是,我能够在模拟器(ARM)中成功引用变量地址,但是在设备(x86)上,事情也没有进行.

将指针从C到Java变为无效

使用该示例来自此链接,我发现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/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。