内容简介:阅读本文前,前先阅读Java 原生接口 (JNI):JNI 是 Java 和 C++ 组件用以互相通信的接口。现在说的是C里的JNIEnv,不是C++里的JNIEnv,有点区别,但是理解了C里的JNIEnv,就理解了C++里的JNIEnv
阅读本文前,前先阅读 JNI-NDK 在AndroidStudio3.2.1版本集成方法(ndk-build方式) ,了解jni在AndroidStudio里的集成步骤
概念
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环境,点进去跳到了
这个文件里
发现 JNIEnv是JNINativeInterface*的别名,JNINativeInterface是什么,发现他是一个结构体,里面列出了许多方法指针,相当于java里的一个类,类里定义了很多方法,这些方法在jni开发中非常重要
看看这个方法是不是很眼熟,NewStringUTF
(*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结构体的一个图示
JNINativeInterface里所有方法的说明看这里: 官方文档
所有方法分为以下几类
看看NewStringUTF的文档
以后会用到很多方法,都可以在这里查询
JNI里的数据类型
在上面的方法里,看到了很多奇奇怪怪的数据类型 jboolean jstring…,他们与java、c是如何对应的
我们在jin.h里还发现了这段代码
查看数据类型的官方文档 文档截图:
参考类型 JNI包含许多与不同类型的Java对象相对应的引用类型。JNI引用类型按层次结构组织,如图3-1所示。
JNIENV在C与C++的区别
我直接复制了上篇博客的内容
- 创建实现头文件的.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++"); }
- 你也可以写个.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就可以直接调用对应的方法了(有点绕)
Android.mk文件
Android.mk是Android提供的一种makefile文件,用来指定诸如编译生成so库名、引用的头文件目录、需要编译的.c/.cpp文件和.a静态库文件等。要掌握jni,就必须熟练掌握Android.mk的语法规范。
参考自 Android.mk用法详解
这个文件rebuild后 androidstudio会自动生成,看我的 上篇博客 可以找到他的生成的路径,有小坑请注意
Application.mk文件
摘自 安卓Application.mk文件的属性说明和基本写法
使用androidstudio开发,不需要这个文件了,可以在gradle里配置相关属性,详情见 此文
静态链接库(.a) 与 动态链接库(.so)
我们编译成功的文件是一个.so文件,我们的C代码就打包在了这个文件中,类似于java的jar包。C编译后的代码有两种格式文件静态链接库(.a) 与 动态链接库(.so) 简单说区别为:
- 静态链接库文件大,里面有你自己写的逻辑,也有引用的其他库函数,但是容易移植
- 动态链接库文件小,公用的代码,可以直接引用,确定是不容易移植,因为so文件里的代码不是独立可以运行的
下面的截图来自 C/C++ 静态链接库(.a) 与 动态链接库(.so) ,想了解更多,请点击查看
静态链接库(.a)
动态链接库(.so)
ABI(应用二进制接口)
我们经常看到下面这个图,会生成多个libxxx.so文件,他们分别在不同的armxxx下面
简单来说,每个手机里的cpu是不同的,不同的cpu对应支持不同的ABI,我们编译出来的so文件,在不同ABI上是不能兼容的,所以我们要针对不同的ABI变移除不同的so文件,这样不同cpu的手机都可以调用到适合自己的so文件。
不同的 Android 手机使用不同的 CPU,而不同的 CPU 支持不同的指令集。CPU 与指令集的每种组合都有专属的应用二进制接口,即 ABI。ABI 可以非常精确地定义应用的机器代码在运行时如何与系统交互。您必须为应用要使用的每个 CPU 架构指定 ABI。—摘自 android官网-ABI 管理
常见的有armeabi、armeabi-v7a、arm64-v8a、x86、x86_64,在abiFilters配置
defaultConfig { ... ndk { moduleName "Java2C" //so文件名,如果这里配置了so文件名字, //记得更改Android.mk里的 //LOCAL_MODULE :字段为 LOCAL_MODULE := Java2C abiFilters "armeabi", "armeabi-v7a", "x86" //指定so文件所支持的CPU类型 //如果不写的话,会生成所有的CPU类型的so文件 } }
小结
至此,关于jni里的一些概念,都了解了一遍,接下来,要敲几个demo,看看具体如何使用这些知识点
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 理解JavaScript概念系列--异步任务
- 轻松理解 Kubernetes 的核心概念
- 理解CSS-BFC概念
- Core Java 并发:理解并发概念
- IOC的概念这样理解更简单
- [译] 轻松理解 Kubernetes 的核心概念
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
C# Primer Plus
Klaus Michelsen / Sams / 2001-12-15 / USD 49.99
C# Primer Plus is a tutorial based introduction to the C# language and important parts of the .Net Framework. Throughout the book the reader will be exposed to proven principles enabling him to write ......一起来看看 《C# Primer Plus》 这本书的介绍吧!