IntelliJ IDEA平台下JNI编程全解

9 篇文章 0 订阅

1、前言

众所周知,Java语言是基于虚拟机的解释性语言(Java代码经过编译器编译之后并不是能够直接在机器上执行的二进制代码,而是JVM虚拟机能够识别的字节码,依靠Java虚拟机进行解释执行)。而C/C++是编译型语言(编译完成后是能够直接在机器上运行的二进制指令)。虽然,随着Java虚拟机技术的改善和优化,Java性能相对于刚出来那会已经有了极大地提升,但是C/C++语言的性能还是会比Java要高,这是不争的事实。并且我们知道,现在很多服务程序都是Java程序编写的,但是有时候,对于服务的某些对性能要求非常高的地方我们希望用C/C++来编写,以满足程序的性能要求。这时候,我们就需要用到JNI技术,通过它Java可以调用C/C++编写的程序。

2、搭建gcc编译环境

JNI既然是使用Java调用C/C++程序,那么我们首先得有一个C/C++编译环境:将C/C++代码编译成相关平台可执行的动态链接库(Windows下的.dll、Linux下的.so、Mac下的.dylib等)。因为我使用的是Mac,因此本文主要以Mac为例进行进行介绍,但是我也会对其它两个平台的方法也会进行介绍。

Linux和Mac电脑一般都会自带gcc编译器,直接在命令行中输入gcc --version就可以查看gcc版本号。如果读者使用的是Windows平台,那么我建议使用MinGW,从相关网站把需要的MinGW下载并将相关库和程序解压到指定目录,假设是D:MinGw。解压完成后,刚才指定的解压目录中的bin加入到path环境变量中。例如上面图中解压到D:\MinGw,那么应当将D:\MinGw\bin加入到环境变量path中。注意,请确保bin目录确实在D:\MinGw中,如果不在,可能在更深一层目录中,自行确定bin的目录。此时,你也可以打开控制台,输入:gcc -v 查看

3、编写Java代码

在IntelliJ IDEA中创建一个Java项目,新建一个类:JNIDemo.java,并编写如下所示代码:
在这里插入图片描述
函数System.loadLibrary()是加载dll(windows)或so(Linux)库,只需名称即可,无需加入文件名后缀(.dll或.so)。native关键字将函数sayHello()声明为本地函数,由C/C++实现。具体的实现就在JNIDemo.dll (Windows平台)、libJNIDemo…so(Linux平台)、libJNIDemo.dylib(Mac)。

4、一键生成头文件

虽然可以手动通过命令生成头文件,但是我觉得比较麻烦,这里我们使用IDEA进行一键生成,依次点击File > Settings > Tools > External Tools
在这里插入图片描述
添加一个先的External Tools:
在这里插入图片描述

在JNIDemo.java文件中 点击右键 > External Tools > Generate Header File

在这里插入图片描述
这是项目目录下的的jni目录下就生成了一个 JNIDemo.h ,内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JNIDemo */

#ifndef _Included_JNIDemo
#define _Included_JNIDemo
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     JNIDemo
 * Method:    sayHello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_JNIDemo_sayHello
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

5、编写C程序并一键生成dll(so或dylib)

接下来我们在jni目录下再创建一个 JNIDemo.c ,内容如下:

#include "jni.h"
#include <stdio.h>
#include "JNIDemo.h"

JNIEXPORT void JNICALL Java_JNIDemo_sayHello (JNIEnv * env, jobject thisObj){
    printf("Hello World!\n");
    return;
}

接下来干嘛?你猜……

按照前面的方法,点击 File > Settings > Tools > External Tools > +,输入内容如下:

  • Windows版
Generate DLL
<GCC路径>
-Wl,--add-stdcall-alias -I"$JDKPath$\include" -I"$JDKPath$\include\win32" -shared -o ./lib/$FileNameWithoutExtension$.dll ./jni/$FileNameWithoutExtension$.c
$ProjectFileDir$
  • Mac版
Generate DLL
<GCC路径>
-dynamiclib -I"$JDKPath$/include" -I"$JDKPath$/include/darwin" -shared -o ./lib$FileNameWithoutExtension$.dylib ./jni/$FileNameWithoutExtension$.c
$ProjectFileDir$

在这里插入图片描述
在HelloJNI.c中点击右键,选择External Tools>Generate DLL。此时,在项目目录中会得到dll文件(别忘了我的是Mac):

在这里插入图片描述

6、运行JNIDemo.java

至此,大功告成,运行结果如下:
在这里插入图片描述

当然,这只是一个最简单的JNI调用,真正项目中需要使用的JNI程序往往是需要Java与C/C++之间进行大量的数据传递。Java与C/C++中的数据传递并不是那么简单的事情,毕竟不同的语言的基本类型都不是完全一样,因此需要严格地按照相关的约定,当然这是我即将在新的篇章中进行详细介绍的。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值