一般我们NDK编程都是Java层调用C++的接口,但其实才C++层也可以调用Java的函数。实现方法如下:

1、获取类名:jclass cls = env->FindClass

2、获取类方法:jmethodID mid = env->GetMethodID

3、获取类成员变量:fieldID fid=env->GetFieldID

4、生成类对象:jobject obj=env->NewObject (jobect也可以从Java层传下来)

5、调用类成员方法:env->CallXXXMethod(XXX为Java方法的返回值类型)

下面是一个例子:

首先是Java的代码,首先生成一个JniTest类,里面有个sayHelloFromJava的方法,我们要实现的目标是在C++里面赋值(String str),两个整形值(int index1,  int index2),一个整形数组(int[] intArray),然后在Java里面将这些数值打印出来。

publicclassJniTestextendsActivity {

/** Called when the activity is first created. */

@Override

publicvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

JNI j = newJNI();

j.write();

}

publicJniTest()

{

Log.i("TEST","JniTest Constructor");

}

publicintsayHelloFromJava(String str,intindex1,intindex2,int[] intArray)

{

Log.i("TEST", str +" But I am show in java");

Log.i("TEST","index1 = "+ index1 +" index2 = "+ index2 );

intjavaIndex =5;

for(inti =0; i

{

Log.i("TEST","intArray[i] = "+ intArray[i]);

}

returnjavaIndex;

}

}

publicclassJNI {

static

{

System.loadLibrary("myjni");

}

publicnativevoidwrite();

}

然后是C++里面的代码

JNIEXPORTvoidJNICALL Java_cc_androidos_jni_JNI_write

(JNIEnv *env, jobject j) {

LOGI("calltest");

jstring str = NULL;

jclass clz = env->FindClass("cc/androidos/jni/JniTest");

//获取clz的构造函数并生成一个对象

jmethodID ctor = env->GetMethodID(clz, "","()V");

jobject obj = env->NewObject(clz, ctor);

// 如果是数组类型,则在类型前加[,如整形数组int[] intArray,则对应类型为[I,整形数组String[] strArray对应为[Ljava/lang/String;

jmethodID mid = env->GetMethodID(clz, "sayHelloFromJava","(Ljava/lang/String;II[I)I");

if(mid)

{

LOGI("mid is get");

jstring str1 = env->NewStringUTF("I am Native");

jint index1 = 10;

jint index2 = 12;

//env->CallVoidMethod(obj, mid, str1, index1, index2);

// 数组类型转换 testIntArray能不能不申请内存空间

jintArray testIntArray = env->NewIntArray(10);

jint *test = newjint[10];

for(inti = 0; i

{

*(test+i) = i + 100;

}

env->SetIntArrayRegion(testIntArray, 0, 10, test);

jint javaIndex = env->CallIntMethod(obj, mid, str1, index1, index2, testIntArray);

LOGI("javaIndex = %d", javaIndex);

delete[] test;

test = NULL;

}

}

通过这个例子我们基本上就可以了解C++层是如何回调Java函数的了。另外,这里还有一个小技巧,如果你不知道你Java层的在C++中的类型是什么,你可以native方法中将这个类型写进去,然后用javah方法生成.h文件,只要查看.h文件的对应的类型注释就可以知道结果了。例如:我们想知道String、整形数组对应的类型怎么写,我们在native中加入一个public native void type(String str, int[] arrayInt)方法

publicclassJNI {

static

{

System.loadLibrary("myjni");

}

publicnativevoidwrite();

publicnativevoidtype(String str,int[] arrayInt);

}

然后生成对应的.h文件:

/*

* Class:     cc_androidos_jni_JNI

* Method:    type

* Signature: (Ljava/lang/String;[I)V

*/

JNIEXPORT voidJNICALL Java_cc_androidos_jni_JNI_type

(JNIEnv *, jobject, jstring, jintArray);

我们注意看注释中的“Signature: (Ljava/lang/String;[I)V”,其中Ljava/lang/String;Ljava/lang/String;就是String的类型(注意分号不能丢),[I则是整形数组对应的类型。

jni回调java类中函数_Andriod JNI编程之C++回调Java函数相关推荐

  1. frida hook java 函数_使用 Frida 来 Hook Java 类中的构造函数(构造函数带重载),获取解密后的js脚本...

    一个APP使用了Auto.js 的加密脚本.我们的任务是将其加密脚本进行解密并dump出来.在  https://www.52pojie.cn/thread-1112407-1-1.html 一文中, ...

  2. 【Groovy】Groovy 脚本调用 ( Java 类中调用 Groovy 脚本 )

    文章目录 前言 一.Groovy 类中调用 Groovy 脚本 1.参考 Script#evaluate 方法分析 Groovy 类中调用 Groovy 脚本 2.创建 Binding 对象并设置 a ...

  3. Shell-通过shell启动Java类中的main方法 + 通过Shell启动jar包

    文章目录 概述 shell启动Java类中的main方法 启动脚本分析 启动脚本 shell启动jar包 概述 Java程序 运行在linux主机上, 通过shell脚本启动为进程. Java程序中 ...

  4. Myeclipse中导入项目后java类中汉字注释出现乱码问题(已解决)

    Myeclipse中导入项目后java类中汉字注释出现乱码问题(已解决) 参考文章: (1)Myeclipse中导入项目后java类中汉字注释出现乱码问题(已解决) (2)https://www.cn ...

  5. Java 类中可以覆盖静态方法吗?

    Java 类中可以覆盖静态方法吗? 不,你不能在Java中覆盖静态方法,但在子类中声明一个完全相同的方法不是编译时错误,这称为隐藏在Java中的方法. 你不能覆盖Java中的静态方法,因为方法覆盖基于 ...

  6. 二十三、Java类中重载和重写的区别

    @Author:Runsen @Date:2020/5/31 作者介绍:Runsen目前大三下学期,专业化学工程与工艺,大学沉迷日语,Python, Java和一系列数据分析软件.导致翘课严重,专业排 ...

  7. java sql范围查询语句,java类中写sql语句,查询条件包含换行

    java类中写sql语句,查询条件包含换行 detachedCriteria.add(Restrictions.or( Restrictions.like("chengBanDanWeiId ...

  8. JSP中调用java类中的方法

    JSP中调用java类中的方法 1.新建一个项目,在src文件夹下添加一个包:如:test 2.再在包中添加一个类:如 package test; public class conDatabase { ...

  9. java类中的static块_java类中static代码块的执行次数

    java类中 static静态代码块的执行次数 1.在类加载的init阶段,类的类构造器中会收集所有的static块和字段并执行,static块只执行一次,由JVM保证其只执行一次. 2.直接看示例 ...

  10. java中类可以包含哪些元素,Java类中包含的元素及作用

    Java类是面试中常考的知识点,是组成Java应用的基本成分,小型和大型的应用都是由类组建而成的.作为合格的Java工程师,一定要清晰了解Java类及其包含的元素及作用,今天学码思Java培训老师就J ...

最新文章

  1. oracle 如何表分析,ORACLE的表分析策略
  2. 用计算机进行资料检索工作是,用计算机进行资料检索工作是属于计算机应用中的什么...
  3. jQuery -- 光阴似箭(五):AJAX 方法
  4. 问题及解决 —— 浏览器问题
  5. 图像处理: 超像素(superpixels)分割 SLIC算法
  6. qqkey获取原理_编译原理(第3版)[刘铭][实验程序源代码]
  7. 区块链是什么通俗解释_区块链是什么?1个例子通俗解释,小白秒懂!
  8. html怎么去除em的倾斜,HTML5 :b/strong加粗,i/em倾斜区别
  9. it职业生涯_如何通过这些有用的网站提升您的自由职业生涯
  10. Linux如何ping本机IP,Linux ping6 本地ipv6地址无效的参数
  11. python for ArcGIS 绘制北京市板块地图
  12. 代码随想录算法训练营第一天|704二分查找 27移除元素
  13. 基于java线上教学平台计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署
  14. 联想y700安装黑苹果_【EFI】联想Y700 I7-6700HQ HD530 GTX 960M 1080P 10.14.6 引导下载
  15. JIL Widget打包
  16. Android实现异步加载图片 ListView
  17. 热加工作业考研题目答案分享——Joining processes 2
  18. LifeKeeper 6.0 for Windows
  19. mysql show tables_mysql show命令用法
  20. Python相关基础信息

热门文章

  1. javascript 判断数据类型的几种方法
  2. 20172328《程序设计与数据结构》第三周学习总结
  3. 2602 最短路径问题
  4. ThinkPHP的A方法,R方法,M方法,D方法区别
  5. 高质量外链该怎样做?
  6. 影像测量仪使用的注意点
  7. python判断文件格式_Python判断上传文件类型
  8. 学习OO,实现的小跟堆代码
  9. linux pagecache与内存占用
  10. 内存中inode与磁盘中inode