JNI中修改(基本类型)参数并返回到Java层使用

JNI中修改(基本类型)参数并返回到Java层使用,第1张

概述最近在JNI相关项目中遇到一个问题:在Java层传入多个int类型的参数,在jni层修改参数值或地址之后重新返回到Java层。这应该算是基本知识了,尤其是基本类型的参数往往看似简单,所以在之前学习jn

  最近在JNI相关项目中遇到一个问题:在Java层传入多个int类型的参数,在jni层修改参数值或地址之后重新返回到Java层。这应该算是基本知识了,尤其是基本类型的参数往往看似简单,所以在之前学习jni时就一笔带过了,结果现在突然遇到这个问题竟然需要再查找资料学习,因此这周在重新复习一遍基础知识之后将此记录一下。走的再远,也不要忘记脚底的路。

  还是用Demo来解释下需求和对应解决方案吧

 1 public class libraryManager { 2  3     static{ 4         System.loadlibrary("libtest"); 5     } 6  7     final static native int add1(int arg1,int arg2,1)">int result); 8     int add2( 9   12 }

 

  在Java层写了两个方法分别模拟这个需求,在底层对arg1arg2参数做 *** 作,之后将结果存入result中,希望能在Java层使用result,至于方法的返回值,则是模拟表示方法执行成功与否的标志位。

下面分别在jni中用两种方式实现该需求,当然这两种都是典型错误的。

JNIEXPORT jint JNICALL Java_com_xxx_libraryManager_add1( 2 jnienv *jenv,jclass jcls,jint jarg1,jint jarg2,jint jarg3){ 3     jarg3=jarg1+jarg2; 4     LOGI("add1 arg3=%d",jarg3); 5     return 1; 6 } 7  8 JNIEXPORT jint JNICALL Java_com_xxx_libraryManager_add2( 9 jnienv *jenv,jint *jarg3){10     int result=jarg1+11     jarg3=&result;12     LOGI(add2 arg3=%d",*jarg3);13     214 }

 

  如果还记得jni的运行原理的话,应该很容易理解这么写只是修改在c线程里边的参数值(add1()中)和参数地址(add2()中),至于Java层对应的参数没有变化,也就是说jni中的基本类型作为参数时只是形参传入的,对于上层没有任何影响。当然如果作为return值的话是绝对可以的,但是现在讨论的是作为参数值的方法。那么还是这个需求,应该怎么解决呢?

  在libraryManager.class中增加两个新的方法

1     int addConfirm1([] result);2     int addConfirm2(int类型转换为int[]addConfirm1()中)和int对应的整型类(addConfirm2()中),当然就是使用jni中的jnienv可以获取到的方法来修改参数,至于具体用法在下面详细列出。

JNIEXPORT jint JNICALL Java_com_bob_testlib_libraryManager_addConfirm1( 4     int *arg3 = jenv->GetIntArrayElements(jarg3,0 5     *arg3= 6     jenv->ReleaseIntArrayElements(jarg3,arg3,1)">3 9 JNIEXPORT jint JNICALL Java_com_bob_testlib_libraryManager_addConfirm2(10 jnienv *11     12     jclass intClass = jenv->FindClass(java/lang/Integer13     jfIEldID intID = jenv->GetFIEldID(intClass,1)">valueI14     jenv->SetIntFIEld(jarg3,intID,result);15     416 }

 

  在addConfirm1()中将int[]的参数传入,这样可以通过jnienvGetIntArrayElements()获取到传入参数的地址并绑定到int*变量中,在修改变量之后,通过ReleaseIntArrayElements()通过第三个参数mode=0更新JavajintArray的参数,并释放JNI层的int*变量。

  在addConfirm2()中将jobject参数传入,通过jnienvFindClass()找到JavaInteger类对应jni层的jclass,再根据jclass通过jnienvGetfiledID()找到JavaInteger类的value对应jni层的jclassjfIEldID,最后通过jnienvSetIntFIEld()将要更新的int值存入到Java层的jobject中即可。这个流程就是把Java层的Integer看成自定义的类,之后就是更新自定义类中的变量。

  目前能想到的有上面两种方式可以解决类似需求,其思想都是将Java中的基本类型转变成Java类,之后再用JNI中对类的 *** 作方法进行修改。

 

总结

以上是内存溢出为你收集整理的JNI中修改(基本类型)参数并返回到Java层使用全部内容,希望文章能够帮你解决JNI中修改(基本类型)参数并返回到Java层使用所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/web/1119329.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存