用java 语言编写的程序能否调用C语言编写的程序类库呢? 同样 C(程序)能否调用 java语言编写的api呢?答案是肯定的!!!!
重要概念 JNI
什么是JNI?
JNI即Java native interface Java本地开发接口 是一个协议,用来沟通Java代码和本地外部代码(c和c++),通过这个协议呢,Java也能调用外部的c代码。c代码也能调用Java代码。
直接上代码
图片.png
非常简单了一个java类代码
-
定义了一个本地方法
private static native String getStringFromC();
native 是声明本地方法的关键字,没有方法体(C语言中有对应的实现)
-
加载C生成的动态库
图片.png
static{ System.loadLibrary("JNI_DEMO"); }JNI_DEMO 是动态的名称,至于它怎么由C语言生成的,且C语言中的代码怎么写后面介绍
-
调用本地方法
System.out.println(getStringFromC());
打印结果:如下图,这个结果是有动态库中的C函数返回的
图片.png
上述,就是Java调用C语言的过程,非常之简单,就三个步骤,你先声明一个本地方法,然后加载C语言动态库,最后调用该方法。
接下来就是重点了
1、java声明的本地方法在C程序中肯定有对应的方法,这个方法怎么实现?
2、怎么由C程序生成动态库?
第1个问题:
在jdk中为我们提供了一个javah命令,它可以帮助我们实现这个本地方法在C语言中的声明。如果你的电脑配置了jdk,那么cmd进入命令行输入“javah”
图片.png
大概了解一下“javah”就行了。接着用javah名称生成C函数的声明,先进入到你的工程中的src目录下,按住“shift” + 鼠标右键。弹出一个窗口,有一个“在此处打开xxx窗口” 点击它,让后在窗口中输入“javah”后跟全类名,回车结束。
图片.png
图中的xxxx.h文件(图中的红色框)就是生成的C的声明文件。
打开它看看它是什么。
图片.png
红色框,就是一个函数的声明,我们发现,它名称由java程序中的包名+类目+本地方法名组成的,(只是中间有下划线间隔开),这就是jni开发中C 函数的名称的命名规则,而且必须是这样,否则java中调用本地方法会找不到动态库中对应的C函数。
有了C函数声明文件,就可以开始写C代码了,创建一个 .c文件,名字随意
图片.png
上述C代码中:include "stdafx.h" 这是C语言预编译声明文件
include "com_zds_study_MainStudy.h" 这个就是刚刚通过javah生成声明文件,在这个文件中包含了<jni.h>头文件
图片.png
jni.h它不是C语言函数库中的文件,它由NDK为我们提供的,什么是NDK呢?
NDK是一系列工具的集合。它提供了一系列的工具,帮助开发者快速开发C/C++的动态库,并能自动将so和java一起打包成apk。
代码中的JNIEnv是什么,jobject是什么等等先放一边,请先把看空色框中的字符串内容,
图片.png
这不是就文章开头Java调用C流程中打印出的“JNI from C”吗,内容就是由这个函数返回的。
至此第一个问题算是勉强理解了,但是还是有很多疑问,比如JNIEnv是什,这个函数的返回值是jstring,为啥不是String呢,原因是C语言中的数据类型和Java不太相同,所以在C中 定义了Java中的数据类型,每个数据类型的名称之前加了一字母“j” (可以理解为java的), 所以java中的int 类型在C中就是“jint”,“jfloat”就是java的float类型等等。所以 jobject你也能联想到是java 的类对象。
至于JNIEnv就不得不看源码了
图片.png
通过源码我们发现它是一个struct JNIInvokeInterface_类型的结构体指针。再看看结构体JNIInvokeInterface_如下图
图片.png
定义了许多函数指针,其中NewStringUTF函数就是将C中的字符转换成java中的String,如下图
图片.png
说白了,这个结构体定义的函数指针和函数都是为了和java交互用的。
第二个问题
怎么生存动态库,我的window10系统上安装了vs2017,由它生成C的动态库很容易了,生成这个动态的后缀是.dll。这是在windows平台下,而Linux平台是.so,安卓开发中经常会使用到第三方提供的.so文件。
图片.png
在window平台下通过交叉编译生成其他平台的动态库,NDK就是一个强大的助手。
下载后解压并配置环境变量(配置与JDK无差异),通过命令行验证是否配置成功(配置成功就可以交叉编译了)。
图片.png
为了C语言的复习,整理一部分笔记。
《JNI开发——基础-C语言 · 一》https://www.jianshu.com/p/476ba321b040
NDK学习准备两套开发环境
-
Android Studio (用于ffmpeg配置与学习)
-
昨天搭建了Eclipse的Android 开发环境(音乐app《唱吧》大牛是基于Eclipse的讲解的)
-
后端开发也是Eclipse,为了避免与AS的 ADT冲突,所以不要在原来的eclipse中配置,下载ADT Bundle,它包含了Eclipse、ADT插件和SDK Tools,是已经集成好的IDE,只需安装好Jdk即可开始开发
整理笔记











网友评论