目录
上一篇博客已经讲了Python与C的交互,本篇主要将JNI的使用和在Android项目中嵌入Python解释器,实现Java与Python相互调用。
1 JNI
JNI,即Java Native Interface。它其实就是一套java与本地代码交互的接口或者说是一个协议。通俗的比喻,就是中国人讲中国话,日本人讲日本话,于是中国人碰到日本人,各说各话,无法交流。如果这个时候,中国人学会了英语,日本人也学会了英语,那么中国人日本人就可以用英语交流了,这就是要学习JNI的原因!Java语言无法直接调用C/C++代码,反之亦然,于是就有了JNI,帮助两者相互调用。当然,这一套机制并不是那么美好,总会有一些坑要踩,就像中国人跟日本人交流还需要借助英语,怎么看都有一些多余,我们直观的感觉就是,讲同一种语言更好。
在Java的JNI参考手册中,明确指出了使用JNI的一些缺陷,因此,在真实项目中,如果要使用JNI,尽量三思而后行。既然JNI不被推荐使用,那么学习JNI的意义是什么呢?作为一个Android平台的开发者,最幸福的事情就是系统开源,这个开源的系统实际上就是一个巨大的宝库,从底层到上层,可以汲取无数的知识,而在Android系统中,JNI技术是被大量使用的,要想深入的研究学习源码,JNI是必须要掌握的一步,因此,就先从Java语言的JNI基础开始吧!
JNI(Java Native Interface),是方便Java调用C、C++等Native代码所封装的一层接口,相当于一座桥梁。通过JNI可以操作一些Java无法完成的与系统相关的特性,尤其在图像和视频处理中大量用到。
NDK(Native Development Kit)是Google提供的一套工具,其中一个特性是提供了交叉编译,即C或者C++不是跨平台的,但通过NDK配置生成的动态库却可以兼容各个平台。比如C在Windows平台编译后生成.exe文件,那么源码通过NDK编译后可以生成在安卓手机上运行的二进制文件.so。
1.1 JNI编写流程
1.2 实例
开发工具:IDEA,JDK8,VS2019。
1.2.1 新建Java JNI接口
使用IDEA新建Java项目“jni_demo”,创建package "com.jni",Java Class “JniDemo”。
public class JniDemo {
//方法一 返回名称
public native String getName();
//方法二 传递一个参数
public native void sayAWord(String prompt);
}
1.2.2 生成Java文件对应的C++ (.h)头文件
(1)第一种方法 直接用jvm命令运行
现在IDEA中build project。
没有错误,会在项目根目录/bin/com/jni下生成JniDemo.class。
在控制台输入
javah -jni com.jni.JniDemo
(2)第二种方法 在IDEA中配置External Tools
IDEA中点击File->Setting->External Tools 点击+,创建“javah”。
- Name:
javah
(可随意指定) - Program:
D:\Installed\Java\jdk1.8.0_251\bin\javah.exe
(javah所在的目录) - Arguments:
-jni -classpath $OutputPath$ $FileClass$
- Working directory:
$ProjectFileDir$
在Java文件上右击点击External Tools->javah生成头文件。
1.2.3 VS2019中实现.h文件生成dll
(1)创建动态链接库工程,工程名为Dll3
对运行环境进行重新设置
右键项目,添加包含目录
添加包含路径:
- D:\Program Files\Java\jdk1.8.0_251\include; //jni.h所在的目录
- D:\Program Files\Java\jdk1.8.0_251\include\win32;
(2)创建com_jni_JniDemo.cpp文件
#include "com_jni_JniDemo.h"
#include <iostream>
using namespace std;
JNIEXPORT jstring JNICALL Java_com_jni_JniDemo_getName
(JNIEnv* env, jobject obj)
{
std::cout << "You are the apple of mine"