JNI和Native两种方法 添加JNA方法
JNI
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);
}
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
/* 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;
}
#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));
}
}
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”);
至此完成,运行即可调用。
JNative
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
#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;
}
#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;
}
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);
}
}
}
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);
}
}
}