加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

将指针从C传递到Java变为NULL

发布时间:2020-12-16 10:19:46 所属栏目:百科 来源:网络整理
导读:我正在开发一个针对x86的 Android应用程序,需要与C进行一些集成.我一直在使用swig / JNI来完成这个技巧,而且大部分内容都在顺利运行.但是,指针一直给我一些错误. 我的问题是我能够在模拟器(ARM)中成功引用变量地址,但在设备(x86)上,事情并不顺利. 使用this l
我正在开发一个针对x86的 Android应用程序,需要与C进行一些集成.我一直在使用swig / JNI来完成这个技巧,而且大部分内容都在顺利运行.但是,指针一直给我一些错误.

我的问题是我能够在模拟器(ARM)中成功引用变量地址,但在设备(x86)上,事情并不顺利.

使用this link中的示例,我发现一旦这个地址转移到Java,C中任何已分配变量的地址就变为NULL.例如…

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位,那么在big-endian架构上,这可能会产生意想不到的结果.

& jresult是指向64位值的指针,因此如果将其转换为指向32位值的指针,那么您将指向两个组成32位字的低位寻址.在大端系统中,这将是最重要的词.因此,在将32位字写入64位值的最高端后,您将获得64位值,这比您预期的大2 ^ 32倍.

如果您的LOGI调用将参数视为32位int,并从64位值隐式向下转换它,那么它将给出0.

你能看出这是否有效吗?

jresult = (jlong) result;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读