文档章节

JNI开发系列①JNI概念及开发流程

逝我
 逝我
发布于 2016/09/22 10:34
字数 1291
阅读 16
收藏 0

接续上个系列C语言基础及指针

引言

在学习了C语言基础之后 ,我们简单的了解了C语言编程的一些范式 , 了解了指针 , 结构体 , 联合体 , 函数 , 文件IO等等 。我们最终的目的是要学会NDK开发 , 而NDK开发就离不开我们的JNI技术 。下面 , 就来开始我们的JNI之旅吧 。

JNI的概念

JNI全称 Java Native Interface , java本地化接口 , 可以通过JNI调用系统提供的API , 我们知道 , 不管是linux还是windows亦或是mac os , 这些操作系统 , 都是依靠C/C++写出来的 , 还包括一些汇编语言写的底层硬件驱动 。java和C/C++不同 , 它不会直接编译成平台机器码,而是编译成虚拟机可以运行的java字节码的.class文件,通过JIT技术即时编译成本地机器码,所以有效率就比不上C/C++代码,JNI技术就解决了这一痛点,下面我们来看看JNI调用示意图:

JNI技术.png 从上图可以得知 ,JNI技术通过JVM调用到各个平台的API , 虽然JNI可以调用C/C++ , 但是JNI调用还是比C/C++编写的原生应用还是要慢一点 , 不过对高性能计算来说 , 这点算不得什么 , 享受它的便利 , 也要承担它的弊端 。

JNI开发流程

因为JNI开发并未涉及到NDK , 所有我们的开发工具是eclipse and visual studio 。

第一步:编写java本地方法

public static native String getStringFromC() ;

第二步:生成.h头文件 , 需要使用到的java命令是javah

# 假定你以配置好java环境
# 在控制台中进入工程src目录
> cd  E:\java_workspace\Hello_JNI\src
> javah com.zeno.jni.HelloJni 
# 需要注意的是 , com.zeno.jni.HelloJni , 是全类名, 包名.类名

第三步:将.h头文件复制到VS的代码文件目录下 , 在解决方案中的头文件目录-> 右键-> 添加 -> 添加现有项 。 将我们的头文件添加进来。

添加头文件.png 添加进来之后 , 打开我们的头文件 , 会发现 , 头文件里面的jni.h这个头文件找不到 , 因为它不是系统的头文件 , 所有我们需要将它找出来 , 并复制到我们的工程项目中 。

# JDK 的jni.h头文件目录
D:\Java\jdk1.8.0_60\include\jni.h
# 在jni.h头文件中,又引入了jni_md.h头文件 , 所有这个我们也要一并赋值过来
D:\Java\jdk1.8.0_60\include\win32\jni_md.h

将jni.h这个头文件按照上述步骤 , 添加到头文件目录中 , 注意将<>改成" "<>表示引入的是系统头文件," "表示引入的是第三方头文件。

第四步:实现头文件

// 生成的头文件函数
/*
 * Class:     com_zeno_jni_HelloJni
 * Method:    getStringFormC
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_zeno_jni_HelloJni_getStringFromC
  (JNIEnv *, jclass);

新建一个.c的文件 ,引入我们生成的头文件 ,然后实现我们生成的C语言函数。

/*
* Class:     com_zeno_jni_HelloJni
* Method:    getStringFormC
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_zeno_jni_HelloJni_getStringFromC
(JNIEnv *Env, jclass jclazz) {

	return (*Env)->NewStringUTF(Env, "Jni C String");
}

第五步:生成动态链接库

补充:

库名称特性扩展名
动态库1.动态库把对一些库函数的链接载入推迟到程序运行的时期。2.可以实现进程之间的资源共享。(因此动态库也称为共享库)3.可以动态注入到程序中win(.dll)linux(.so)
静态库1.静态库对函数库的链接是放在编译时期完成的。2.程序在运行时与函数库再无瓜葛,移植方便。3.浪费空间和资源,因为所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件。win(.lib)linux(.a)

了解了静态库和动态库 , 下面我们就来生成一个动态库,以VS为例:

选中项目 -> 右键 -> 属性 -> 常规 -> 项目默认值 -> 配置类型 , 选择动态库.dll

项目属性配置.png 配置完成之后 , 选中项目 -> 生成 。即可生成动态链接库。

动态链接库.png

第六步:配置环境变量

我们生成了.dll文件之后 , java环境并不知道有这个.dll动态链接库的存在 , 所有我们需要将生成.dll的文件目录 , 配置到环境变量中。

配置环境变量.png

注意:配置好环境变量 , 需要重新启动eclipse ,不然会找不到动态链接库的。

第七步:加载动态链接库

static{
		System.loadLibrary("Hello_JNI") ;
	}

第八步 : 调用本地方法并执行

/**
 * 
 * @author Zeno
 *
 *	JNI (Java Native Interface) java本地化接口
 *	
 *	Android Framework层与Native层相互通信的基石
 *	
 *
 */
public class HelloJni {
    // java调用C/C++函数的本地方法
	public static native String getStringFromC() ;
	
	public static void main(String[] args) {
		
		System.out.println("getStringFormC == "+getStringFromC());
	}
	
	static{
        // 加载动态库
		System.loadLibrary("Hello_JNI") ;
	}
}

输出:

getStringFormC == Jni C String

JNI 开发的步骤虽然多 , 但大多比较简单 , 操作起来不难 。

结语

这篇是JNI系列的开篇 , 总体来说比较简单 , 先将流程走顺了 , 后续的开发就会好很多 , 流程性的东西 , 需要多操作 , 就会形成固定的套路 。

© 著作权归作者所有

逝我
粉丝 4
博文 20
码字总数 31426
作品 0
长沙
程序员
私信 提问
Android NDK开发简介

最近由于项目的需要,使用到了Android的NDK技术,对项目核心算法跨平台的移植。简答而言,就是使用C对原来的算法进行了改进,并集成到原来的app项目里。 从前的项目一直没有使用NDK进行开发的...

zhiweiofli
2013/03/07
2.2K
0
android SDL系列讲解(十三) 播放音乐库 SDL_mixer教程

项目外包项目信息更新: qq抢红包,因为评估时间问题,没有对接下来。 一个网页开发项目,已经内部消耗掉了。 机会总是稍纵即逝,有兴趣探讨技术,以及项目事宜,可以联系代码GG微信: code...

代码GG陆晓明
2017/10/28
0
0
JNI中调用任何标准输入输出处理流(std::stream)导致JVM崩溃?

大家好,我是JNI萌新!最近碰到一个很无解的问题,如标题所言。然后我也在Stackoverflow上搜索了一番,发现一个和我差不多的问题;但是解决办法对我没什么作用,我也在Stackoverflow上Post了...

frank_123
2017/05/08
288
4
Android OpenGL开发目录

Android OpenGL开发目录 Android OpenGL开发1--VS2017+OpenGL环境的配置 to be continued... 其它目录 Android NDK开发之旅 目录 Android NDK开发之旅1--NDK介绍 Android NDK开发之旅2--C语言...

香沙小熊
2018/01/07
0
0
Android NDK开发之旅 目录

Android NDK开发之旅 目录 Android NDK开发之旅1--NDK介绍 Android NDK开发之旅2--C语言--基本数据类型 Android NDK开发之旅3--C语言--指针 Android NDK开发之旅4--C语言--动态内存分配 Andr...

香沙小熊
2017/12/31
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Excption与Error包结构,OOM 你遇到过哪些情况,SOF 你遇到过哪些情况

Throwable 是 Java 中所有错误与异常的超类,Throwable 包含两个子类,Error 与 Exception 。用于指示发生了异常情况。 Java 抛出的 Throwable 可以分成三种类型。 被检查异常(checked Exc...

Garphy
19分钟前
2
0
计算机实现原理专题--二进制减法器(二)

在计算机实现原理专题--二进制减法器(一)中说明了基本原理,现准备说明如何来实现。 首先第一步255-b运算相当于对b进行按位取反,因此可将8个非门组成如下图的形式: 由于每次做减法时,我...

FAT_mt
昨天
6
0
好程序员大数据学习路线分享函数+map映射+元祖

好程序员大数据学习路线分享函数+map映射+元祖,大数据各个平台上的语言实现 hadoop 由java实现,2003年至今,三大块:数据处理,数据存储,数据计算 存储: hbase --> 数据成表 处理: hive --> 数...

好程序员官方
昨天
7
0
tabel 中含有复选框的列 数据理解

1、el-ui中实现某一列为复选框 实现多选非常简单: 手动添加一个el-table-column,设type属性为selction即可; 2、@selection-change事件:选项发生勾选状态变化时触发该事件 <el-table @sel...

everthing
昨天
6
0
【技术分享】TestFlight测试的流程文档

上架基本需求资料 1、苹果开发者账号(如还没账号先申请-苹果开发者账号申请教程) 2、开发好的APP 通过本篇教程,可以学习到ios证书申请和打包ipa上传到appstoreconnect.apple.com进行TestF...

qtb999
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部