美文网首页Android-NDK/JNI我爱编程
《JNI开发——Java与C之间的桥梁 二》

《JNI开发——Java与C之间的桥梁 二》

作者: Oneminute | 来源:发表于2018-03-07 22:49 被阅读67次

用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即可开始开发

整理笔记

相关文章

网友评论

    本文标题:《JNI开发——Java与C之间的桥梁 二》

    本文链接:https://www.haomeiwen.com/subject/wiysfftx.html