JNI系列之入门Hello JNI C(一)

JNI系列文章:java

  1. JNI系列之入门Hello JNI C(一)
  2. JNI系列之入门Hello JNI C(二)
  3. JNI系列入门之C语言与Java的双向通讯(一)
  4. JNI系列入门之C语言与Java的双向通讯(二)
  5. JNI系列入门之C语言中文字符串乱码问题

1、概述

Java发展至今流行度和覆盖广度已经遍及各行各业,这依赖于它的跨平台,易于入门编写,强大的社区,带来的各类各样的框架,以及功能API库。然而仍是有它的局限性,好比Java的安全性(Java容易被反编译)、性能、内存管理(成也垃圾回收,败也垃圾回收),正式程序员没法直接的管控到内存,才容易致使内存泄漏GC没法回收。为了解决这些问题使用更加高效的c/c++,因而出现了JNI(Java Native Interface)Java本地接口,便于java语言和c/c++语言的通讯。c++

注意前方高能: 学习JNI必须有C/C++的基础,不然Native层的工程代码你会只知其一;不知其二,甚至一路懵逼,严重的易致使扔鼠标、砸电脑,而后就是入门到放弃程序员

2、环境搭建

  1. Java代码的编写目前使用Eclipse,C/C++的代码编写以及编译运行环境是Visual Studio + Windows 64位
  2. 首先配置Java的 jdk环境变量,这个对于一个java的老司机来讲太简单了很少说。
  3. 安装好Visual Studio这个也不用说,问度娘,个人VS版本是:Visual Studio community 2015,安装包有点大,安装挺快的,也就大概一天吧,哈哈哈哈哈哈哈哈哈。

3、编码实现

  • Java代码 使用Eclipse建立一个普通的Java Project,而后建立一个类:JniTest
package com.jerry.jnitest;
public class JniTest {

	public static void main(String[] args) {
		
	}
}
复制代码

在类中写入native的方法(就是java调用C/C++的方法)windows

/** * 经过jni,获取c中返回的字符串 * @return 字符串 */
public native static String getStringFromC();
复制代码

完整代码以下:安全

package com.jerry.jnitest;
public class JniTest {

	public static void main(String[] args) {
        // 调用native方法,获取C中返回的字符串数据
		String text = getStringFromC();
		System.out.println(text);
	}
	
	static {
		System.loadLibrary("JniStudy");
	}
	
	/** * 经过jni,获取c中返回的字符串 * @return 字符串 */
	public native static String getStringFromC();
}
复制代码
  • 生成C中使用的native方法头文件 (若是配置好了jdk的环境变量,正常状况下不会有问题),cmd终端下输入以下命令,当前终端目录必须在java工程的src路径下: 命令:javah com.jerry.jnitest.JniTest(native方法所在类的全名) 框架

    生成native方法的头文件.png
    通常状况生成的头文件都在src目录下。

  • 建立C语言工程,拷贝头文件至工程目录 使用VS建立空的项目JniStudy,将头文件拷贝到JniStudy目录中 函数

    Paste_Image.png
    在VS中的解决方案里右击添加现有项把头文件添加进来:
    Paste_Image.png
    打开头文件这时候你会发现头文件的代码有红色波浪线#include <jni.h>出错了,那是由于jni.h的头文件没有包含进来,这个头文件能够在JDK安装目录的include文件夹里能够找到,由于jni.h自己也引用了jni_md.h头文件,因此也要包含进来,一样能够在JDK安装目录的include下能够搜索到。

  • 在VS中建立一个01.c的源文件用来实现头文件中的native函数:post

#include "com_jerry_jnitest_JniTest.h"
JNIEXPORT jstring JNICALL Java_com_jerry_jnitest_JniTest_getStringFromC (JNIEnv *env, jclass jcls) {
    char *str = "Hello Jerry welcome to Jni World!";
	return (*env)->NewStringUTF(env, str);
}
复制代码

这个就是实现return一个C的字符串。这样native函数就实现了,接下来就是生成动态连接库供java来调用native方法。性能

  • 先将VS的编译环境改为你的系统的,个人windows 64位:
    Paste_Image.png
    Paste_Image.png
    修改编译运行的文件:
    Paste_Image.png
    接下来生成动态连接库
    Paste_Image.png
    生成的是windows下的dll,生成的文件在工程目录的x64/debug/jni_study.dll

Paste_Image.png

  • 将动态连接库所在的目录配置到系统的Path环境变量里:
    Paste_Image.png
    若是你不限麻烦的话,也能够将生成的动态库拷贝到Java工程的更目录下。
  • 环境变量配置好后,重启Eclipse
  • 而后运行Java工程的JniTest这个类。 运行结果:
    Paste_Image.png
    看这个是main方法里调用 getStringFromC()的native方法,C工程代码返回来的字符串:Hello Jerry welcome to Jni World!

4、总结

  1. 在java工程编写native方法
  2. 使用javah 命令生成头文件
  3. 拷贝头文件到C工程,以及相应的jni.h、jni_md.h头文件
  4. 实现头文件的native方法
  5. 修改VS编译运行环境,配置项改为生成dll动态库
  6. 生成解决方案,配置dll动态库所在目录到系统环境变量
  7. 重启Eclipse,运行java工程

JNI系列文章:学习

  1. JNI系列之入门Hello JNI C(一)
  2. JNI系列之入门Hello JNI C(二)
  3. JNI系列入门之C语言与Java的双向通讯(一)
  4. JNI系列入门之C语言与Java的双向通讯(二)
  5. JNI系列入门之C语言中文字符串乱码问题