JNI使用进阶

栏目: C++ · 发布时间: 6年前

内容简介:Java 原生接口 (JNI):JNI 是 Java 和 C++ 组件用以互相通信的接口。现在说的是C里的JNIEnv,不是C++里的JNIEnv,有点区别,但是理解了C里的JNIEnv,就理解了C++里的JNIEnv上面的代码里第一个参数是JNIEnv,这是个什么东西,顾名思义jni环境,点进去跳到了

Java 原生接口 (JNI):JNI 是 Java 和 C++ 组件用以互相通信的接口。

理解JNI

先说说JNIEnv

现在说的是C里的JNIEnv,不是C++里的JNIEnv,有点区别,但是理解了C里的JNIEnv,就理解了C++里的JNIEnv

# include "jni_study_com_jnibsetpractice_Jni.h"

JNIEXPORT jstring JNICALL Java_jni_study_com_jnibsetpractice_Jni_sayHello
        (JNIEnv *env, jobject instance) {
    return (*env)->NewStringUTF(env, "Hello from C");
}
复制代码

上面的代码里第一个参数是JNIEnv,这是个什么东西,顾名思义jni环境,点进去跳到了

JNI使用进阶

这个文件里

JNI使用进阶

发现 JNIEnv是JNINativeInterface*的别名,JNINativeInterface是什么,发现他是一个结构体,里面列出了许多方法指针,相当于java里的一个类,类里定义了很多方法,这些方法在jni开发中非常重要

JNI使用进阶

看看这个方法是不是很眼熟,NewStringUTF

JNI使用进阶
(*env)->NewStringUTF(env, "Hello from C");

调用了这个方法,制造了一个字符串返给了java,你会问不就是一个字符串吗,我直接"Hello from C"返回不就行了吗?不行的,你知道C里是没有过String类型的,C里的"xxx",java并不认识,这就需要jni (java native interface),即【java 与本地语言(C/C++)接口】来解决这个问题

看看这个方法,传入一个*env和char *,char*就是C里的字符串类型,返回了jstring(jstring是java里的String的等价物),这样就把C里的字符串转换成java可以是别的字符串,你说这个方法重要吗,他是结构体JNINativeInterface提供的。

除了这个方法,其他很多方法都很重要,他的作用基本上就是一些jni开发中,常用到的一些方法,为我们在C和Java之间搭建了一座桥梁,让彼此互相沟通

下图是JNINativeInterface结构体的一个图示

JNI使用进阶

JNINativeInterface里所有方法的说明看这里:官方文档

所有方法分为以下几类

JNI使用进阶

看看NewStringUTF的文档

JNI使用进阶

以后会用到很多方法,都可以在这里查询

JNI里的数据类型

在上面的方法里,看到了很多奇奇怪怪的数据类型 jboolean jstring...,他们与java、c是如何对应的

我们在jin.h里还发现了这段代码

JNI使用进阶
JNI使用进阶

查看数据类型的官方文档 文档截图:

JNI使用进阶

参考类型 JNI包含许多与不同类型的Java对象相对应的引用类型。JNI引用类型按层次结构组织,如图3-1所示。

JNI使用进阶

JNIENV在C与C++的区别

我直接复制了上篇博客的内容

  1. 创建实现头文件的.cpp源文件 接下来要写个c++代码,实现这个jni接口

˙注意这里新建的是c++代码,c++代码对应下面的代码

//引入刚才生成的头文件
#include "ndkold_study_com_ndkolddemo_Java2CJNI.h"

//复制头文件里的要实现的方法名及其参数
JNIEXPORT jstring JNICALL
Java_ndkold_study_com_ndkolddemo_Java2CJNI_java2C(JNIEnv *env, jobject instance) {
//    实现这个方法,返回一个字符串
    return env->NewStringUTF("Hello from C++");
}
复制代码
  1. 你也可以写个.c源文件,其对应代码为
//引入刚才生成的头文件
#include "ndkold_study_com_ndkolddemo_Java2CJNI.h"

//复制头文件里的要实现的方法名及其参数
JNIEXPORT jstring JNICALL
Java_ndkold_study_com_ndkolddemo_Java2CJNI_java2C(JNIEnv *env, jobject instance) {
//    实现这个方法,返回一个字符串
    return (*env)->NewStringUTF(env, "Hello from C");
    //注意这里是(*env),而且需要传递一个参数(env)
}
复制代码

说明:c与c++就这点区别,查看jni.h文件,发现在c里的JNIEnv是结构体指针JNINativeInterface*的别名,所以JNIEnv *env相当于二级指针,现在要调用JNINativeInterface*里的方法,要用(*env)->xxx

在c++里JNIEnv是_JNIEnv的别名,在_JNIEnv内部里有个属性为结构体指针JNINativeInterface*,然后他把所有c里的方法都重新定义了一下,定义方式就是通过JNINativeInterface*调了一遍所有c里的方法,而且把JNINativeInterface*的对象以this方式传递进去了,可见这里的JNIEnv *env是一个一级指针,所以通过env就可以直接调用对应的方法了(有点绕)

JNI使用进阶
JNI使用进阶
JNI使用进阶

Android.mk文件

Android.mk是Android提供的一种makefile文件,用来指定诸如编译生成so库名、引用的头文件目录、需要编译的.c/.cpp文件和.a静态库文件等。要掌握jni,就必须熟练掌握Android.mk的语法规范。

参考自Android.mk用法详解

JNI使用进阶

这个文件rebuild后 androidstudio会自动生成,看我的上篇博客可以找到他的生成的路径,有小坑请注意


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Agile Web Development with Rails, Third Edition

Agile Web Development with Rails, Third Edition

Sam Ruby、Dave Thomas、David Heinemeier Hansson / Pragmatic Bookshelf / 2009-03-17 / USD 43.95

Rails just keeps on changing. Rails 2, released in 2008, brings hundreds of improvements, including new support for RESTful applications, new generator options, and so on. And, as importantly, we’ve a......一起来看看 《Agile Web Development with Rails, Third Edition》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

URL 编码/解码
URL 编码/解码

URL 编码/解码