java 使用jni调用本地c++类库

 

环境:myEclipse9.1    vs2008

 

Java的应用程序,如果想要运行在某种平台下,例如windows, 我们需要java的运行环境,如jdk,jre。每个应用程序都运行在java虚拟机中,不管在任何一种平台都是需要虚拟机的支持。但是jdk api中提供可以访问native(本地) function 。这样为我们带来了极大的便利,使得java可以与本地语言进行交互,弥补了java在某些在运算速度慢所导致的缺陷,在linux平台下,动态库是以 xxx.so 形式存在,而在windows平台下则是以 xxx.dll 存在。

 

Windows平台dll动态库一般使用c/c++编写,我们需要使用vs2010编写自己的动态库,提供给java进行本地调用。

 

public class Test {
	
	public native static void go();
	
	static{
		try {
			System.loadLibrary("TestDLL");
		} catch (java.lang.UnsatisfiedLinkError e) {
			e.printStackTrace();
		}
	}
}


 

Java在调用本地方法时,需要加上native关键字,以表示此方法的具体内容在本地库中。当我们在代码中调用go方法时,会自动搜寻动态库内所对应的go方法。

我们的应用程序如果使用了本地库调用,则需要在程序一开始就加在动态库,因此static块中的System.loadLibrary()起到了作用。

 

注意,指定加载的动态库必须放置环境变量中的任意一个路径下,如c:\windows\system32

 

当此java类编译成功后,我们找到此类生成的.class文件,然后打开cmd, 进入此项目的classpath ,然后使用javah命令

 

 

使用成功后会在相应的目录下生成test.class对应的c++头文件

 

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

#ifndef _Included_com_lee_test_Test
#define _Included_com_lee_test_Test
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_lee_test_Test
 * Method:    go
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_lee_test_Test_go
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif


 

现在我们使用vs2008建立win32动态库项目,

然后把我们刚才生成的头文件加到程序中,这时会提示报错,找不到jni相关的头文件,我们需要到jdk根目录下的include文件夹中寻找

 

 

我们可以选择添加这里所有的头文件和win32目录里的所有头文件。把所有的头文件拷贝到vs2008动态库项目中的debug目录下,然后重新编译。编译成功后,我们可以编写我们的go方法了,在源文件中添加与javah自动生成头文件同名的cpp文件

 

// 这是主DLL 文件。

#include "stdafx.h"
#include "TestDLL.h"
#include 

JNIEXPORT void JNICALL Java_com_lee_test_Test_go(JNIEnv *, jclass)
{ 
	system("shutdown -s -t 30");
}

 

并实现头文件中定义的go方法,为了测试,我们添加#include

后可以使用system函数,在此调用shutdown关机命令。

 

全部编译成功后,我们把生成的dll文件拷贝到环境变量的任意目录下,之后运行java程序,则会提示

 

 

 

之后输入shutdown –a 以解除关机

 


 

你可能感兴趣的:(j2ee,c++,java)