JNI:Java调用C接口的方法(1)

JNI基本概念:

  • JNIEnv: Java的本地化环境。C/c++访问Java的对象、类等通过JNIEnv,它里面包含了所有的API。只要和Java交互的都需要它。
  • JavaVM:Java虚拟机。在一个进程里是可以创建很多个虚拟机的。但是对于Android来说,一个进程对应一个VM。每个APP对应一个JavaVM.JavaVM就是来获取JNIEnv的。它有个方法getEnv()。JNIEnv与JavaVM的关系是一个JavaVM里有很多个线程,那么每个线程对应一个JNIEnv。
  • 线程。JNIEnv与线程是一一对应的。在C层去想问Java层,必须是在当前的线程下,获取到当前线程的JNIEnv,才能进行访问。否则在其他的线程里去访问另外一个线程的JNIEnv会导致Crash。

Java去调用C的过程:【以上篇文章创建的DEMO为例子】

用Java去访问C层的接口。

需要在Java层做如下事情:

  • 创建native方法。[native表明了c/c++的接口]

仿写:

鼠标移到yinleiFromJNI上面,会有一个灯泡,可以快速创建C层的代码:

JNIEnv *env, jobject thiz这2个参数。

刚刚介绍了JNIEnv这是我们访问java都可以通过它去访问。

jobject 就是谁调用了这个api,就会把这个java对象当作参数传进来,传进来的时候就是通用类型的object,前面加个j就是jnienv专门为java对象设计的一个类型jobject。

在Java层没有输入任何参数,但是在生成的代码中却包含了上面的2个参数。再看模板

模板里也有这2个参数。这2个参数实际就是Java虚拟机在调用c/c++接口的时候传进来的。也就是说,Java的api通过Java调用我们前面标识的native的方法的时候,最终调用的是java虚拟机里的。Java虚拟机最终会将我们的线程环境jnienv以及调用这个方法的java对象传进来。这样在java层就可以做很多事情。有了这个java对象可以调用这个对象所提供的方法或者属性。有了这个jnienv、线程对象就知道我当前是在这个线程里做的,就直接通过env对象去调用这个相应的方法。然后通过env调用newStringUTF【Java的一个对象】,并传入了一个yinlei的字符串。它就会把c/c++的一个String转成Java对象返回回去。

  • java层的native方法传入参数的时候:

无论我们传什么,它最终都会转换为jobject。

改写下它:

上述代码通过getStringUtfchars将java层的string转成了char *,拿到char *后就可以做一些操作了。

然后看到上面中的releaseStringUTFChars,是释放相应的资源。【毕竟c/c++中申请指针内存还要释放的嘛】

然后return 返回值。

然后运行查看结果:

ok,符合预想预期。


总结,编写方法时候:

  1. 在java层编写native的api
  2. 在c++层实现该api
  3. c++做相应的逻辑然后返回给java层,java层再做显示
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

醒不了的星期八

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值