环境: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 <cstdlib>
JNIEXPORT void JNICALL Java_com_lee_test_Test_go(JNIEnv *, jclass)
{
system("shutdown -s -t 30");
}
并实现头文件中定义的go方法,为了测试,我们添加#include <cstdlib>
后可以使用system函数,在此调用shutdown关机命令。
全部编译成功后,我们把生成的dll文件拷贝到环境变量的任意目录下,之后运行java程序,则会提示
之后输入shutdown –a 以解除关机