1、JNI简介
JNI是Java Native Interface的缩写,中文为JAVA本地调用。从Java1.1开始,Java Native Interface(JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。
2、使用方法
a) 创建java文件:NativeTest.java。内容如下:
package com.bj58; public class NativeTest { public native int add(int x, int y); }
进入项目目录,编译NativeTest.java。命令:
javac NativeTest.java
生成此方法对应的c++的头文件, com_bj58_NativeTest.h。命令:
javah com.bj58.NativeTest //这里是类名
必须在com同级目录下如上执行命令,执行后,可在此目录下生成.h文件;如果是eclipse就在bin目录下执行。
b) com_bj58_NativeTest.h类容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_bj58_NativeTest */ #ifndef _Included_com_bj58_NativeTest #define _Included_com_bj58_NativeTest #ifdef __cplusplus extern "C" { #endif /* * Class: com_bj58_NativeTest * Method: add * Signature: (II)I */ JNIEXPORT jint JNICALL Java_com_bj58_NativeTest_add (JNIEnv *, jobject, jint, jint); #ifdef __cplusplus } #endif #endif
这一部分自动生成,没什么可说的。
c) 根据com_bj58_NativeTest.h 写相应的.cpp文件;
#include "com_bj58_NativeTest.h" #include <iostream> using namespace std; JNIEXPORT jint JNICALL Java_com_bj58_NativeTest_add (JNIEnv * env, jobject obj, jint x, jint y) { return x + y; }
其中在com_bj58_NativeTest.h中有一个#include <jni.h>
此头文件在 %JAVAHOME%/include中,将其copy到你的项目,将<>改为””;打开jin.h文件,其中有一个jni_md.h文件,也将其拷贝到你的项目下;
因为最终要生成动态链接库供java调用,因此如何生成DLL也很重要。
最终生成NativeTest.dll。
d) 调用,在第一步NativeTest.java中实现调用,如:
public class NativeTest { static{ System.loadLibrary("NativeTest"); //c++的dll名 } public native int add(int x, int y); public static void main(String[] args) { NativeTest test = new NativeTest(); System.out.println(test.add(20, 48)); } }
其中System.loadLibrary("NativeTest"); 是将此DLL加载到java程序,
NativeTest.dll要放置在系统环境变量下,比如System32下;
也可以用System.load(“c:\\NativeTest.dll”);
至此完成,运行即可调用。
1、JNative简介
JNative是基于JNI的一个开源实现工具。可以根据现有的DLL直接调用内部方法。
2、使用方法
a) 将现有的dll放在系统环境变量中,如System32;或者在调用的时候使用
System.load(“c:\\NativeTest.dll”);
我的dll生成文件:
NativeTest.h :
#ifndef NATIVETEST_H #define NATIVETEST_H extern "C" int __declspec(dllexport)add(int x, int y); #endif
NativeTest.cpp :
#include "NativeTest.h" int add(int x, int y) { return x + y; }
最终生成NativeTest.dll
b) 调用
public int add(int x, int y) { JNative PegRoute = null; try { if (PegRoute == null) { System.load("C:\\Users\\58\\Desktop\\jnative\\NativeTest.dll"); //加载dll // 1. 利用org.xvolks.jnative.JNative来加载DLL:参数1.NativeTest为类名 // 2.add方法名 PegRoute = new JNative("NativeTest", "add"); // 2.设置要调用方法中的参数:0 表示第一个以此类推 PegRoute.setParameter(0,Type.INT, String.valueOf(x)); PegRoute.setParameter(1, Type.INT, String.valueOf(y)); // 3.设置返回参数的类型 PegRoute.setRetVal(Type.INT); // 4.执行方法 PegRoute.invoke();// 调用方法 } System.out.println("调用的DLL文件名为:" + PegRoute.getDLLName()); System.out.println("调用的方法名为:" + PegRoute.getFunctionName()); System.out.println("返回值为:" + PegRoute.getRetVal()); // 5.返回值 return Integer.parseInt(PegRoute.getRetVal()); } catch (NativeException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } finally { if (PegRoute != null) { // 6.释放系统资源 try { PegRoute.dispose(); } catch (NativeException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } return 0; }
需加载JNative.jar,官网下载即可
至此完成调用
JNA
JNA调用c++库则更为简单。库我们依然使用jnative中生成的c++库NativeTest.dll。
import com.sun.jna.Library; import com.sun.jna.Native; public class JNATest { static { System.load("C:\\Users\\58\\Desktop\\jnative\\NativeTest.dll"); } /** * 定义库中所含接口 * * */ public interface NativeTest extends Library { public int add(int x, int y); } public static void main(String[] args) { //导入库 NativeTest nt = (NativeTest) Native.loadLibrary("NativeTest", NativeTest.class); if (nt != null) { int x = nt.add(10, 36);//具体调用 System.out.println(x); } } }至此完成调用
Vs2010生成dll方法
JNative官网