java通过JNI调用DLL文件

JNI简介:

JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。允许Java代码和其他语言写的代码进行交互。JNI是JDK提供的一个native编程接口。JNI 允许Java程序调用其他语言编写的程序或者代码库, 比如C/C++。Java 在内存管理和性能上有一定的局限,通过JNI我们就可以利用Native程序来克服这些限制

具体示例:

写一个java调用c的加减乘除的dll文件

1、先在编辑器中写好java代码如:

package com.li.dll;


/**
 * @author MR.li
 *	java通过JNI调用DLL文件
 */	
public class JToDll {
	//加载DLL库的方法 System.loadLibrary()
        //不用指定后缀".dll"
	static {
		System.loadLibrary("Math");
	}
	//DLL库中对应的方法
	public native int dll_add(int a,int b); //加法
	public native int dll_sub(int a,int b); //减法
	public native int dll_mul(int a,int b); //乘法
	public native int dll_div(int a,int b); //除法
	
	public static void main(String[] args) {
		
		JToDll dll = new JToDll();
		int add = dll.dll_add(2, 3);
		int sub = dll.dll_sub(8, 5);
		int mul = dll.dll_mul(5, 6);
		int div = dll.dll_div(20, 4);
		
		System.out.println("add="+add+";sub="+sub+";mul="+mul+";div="+div);
	}
	/*
	 * native 关键字告诉编译器(其实是JVM)调用的是该方法在外部定义,这里指的是C。
	 */
}

2、对你写好的这个java进行编译成class文件,在eclipse的话可以直接拿到class文件,在这里我用cmd命令进行编译

java通过JNI调用DLL文件_第1张图片

3、使用javah命令生成c所需要的头文件

在cmd中进入到你项目所在的bin目录然后执行cmd命令,

注意:没有.class  而且 如果有包名的话 记得要把包名也写上

java通过JNI调用DLL文件_第2张图片

执行cmd命令后会在你的bin目录下生成.h的头文件

java通过JNI调用DLL文件_第3张图片

4、使用vs2017创建dll动态链接库

点击右上角文件选择新建项目

java通过JNI调用DLL文件_第4张图片

 之后会有一个弹出框,选择右边的windows桌面和左边的动态链接库,下边的名称是这个dll动态链接库项目的名称、位置是这个项目的存放位置

java通过JNI调用DLL文件_第5张图片

最后点击确定就创建项目了如:

java通过JNI调用DLL文件_第6张图片

5、在C/C++项目中导入头文件

此时出了导入刚刚生成的.h文件,还需要导入java的头文件 jni.h 和jni_md.h

jni.h 以及jni_md.h的路径在 java的安装位置下的include文件夹内 以及win32下

java通过JNI调用DLL文件_第7张图片

 导入顺序为先导入刚创建的项目,其次在导入编辑器中如:

 

java通过JNI调用DLL文件_第8张图片

java通过JNI调用DLL文件_第9张图片

如果跳过项目文件夹导入直接导入到编辑器中是会报错的,原因是在项目中找不到这个文件

6、编写程序并打包DLL库

// Math.cpp : 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"

#include "jni.h"
#include "jni_md.h"
#include "com_li_dll_JToDll.h"



JNIEXPORT jint JNICALL Java_com_li_dll_JToDll_dll_1add(JNIEnv *, jobject, jint a, jint b) {
	return a + b;
}
JNIEXPORT jint JNICALL Java_com_li_dll_JToDll_dll_1sub(JNIEnv *, jobject, jint a, jint b) {
	return a - b;
}
JNIEXPORT jint JNICALL Java_com_li_dll_JToDll_dll_1mul(JNIEnv *, jobject, jint a, jint b) {
	return a * b;
}
JNIEXPORT jint JNICALL Java_com_li_dll_JToDll_dll_1div(JNIEnv *, jobject, jint a, jint b) {
	return a / b;
}

其中的函数直接从你生成的头文件中赋值粘贴拿过来把函数的内容自己补上就可以

注意:编译的时候有x86和x64的选择,区别是x84是32位的x64是64位的

编译时可能还报找不到jni.h的错误,可以将#include 改为#include "jni.h",因为前者是引用系统头文件的写法

点击顶部的生成选择生成解决方案进行编译:

java通过JNI调用DLL文件_第10张图片

在底部会有编译的信息其中就有生成的dll文件路径:(这里我选择是是64位因为我的jdk是64的——根据自己需要来选择生成对应的文件)

java通过JNI调用DLL文件_第11张图片

打开文件看一下

java通过JNI调用DLL文件_第12张图片

7、将生成的dll文件放入System32下(64位放入SysWOW64下)或者放入项目文件中(访问System32下的可以跳过这一步)

 

我在这里直接放入项目中,新建lib文件夹将Math.dll文件放入最后右键项目build Path ->Configure Build Path->Libraries->Native library location双击编辑路径选择为项目下的lib文件夹

java通过JNI调用DLL文件_第13张图片

8、加载dll文件运行项目

注意加载时不用指定后缀".dll"

java通过JNI调用DLL文件_第14张图片

运行结果:

java通过JNI调用DLL文件_第15张图片

 

java与JNI数据类型对应表

JNA调用dll文件

 

你可能感兴趣的:(java基础,JNI,java调用dll文件)