通常我们在写大型项目时,也就是集成的项目时,单独用JAVA语言去完成所有的事情往往效果不佳,也不能很好的完成,例如:我们要去调硬件,获取电脑的运行状况等等(如果用JAVA语言实现时,往往耗时),基于此,我们就要寻求一种很好的解决方案,那就是利用别的语言的长处了,如:C++(它在对底层的调用和硬件方面确实够强悍)。如果我们能用C++实现对硬件的所有操作,然后我们再用JAVA去调C++实现的东西,那不是很完美了,鉴于这样的情况,我们的JNI就应运而生了,我们都知道,JNI调C++实现的东西也就是去调C++运行时生成的*.DLL文件,此时问题就出现了,我们通常调DLL都用1、System.load(String filename); //指定加载的dll全路径文件名;2、System.LoadLibrary(String dllname); //指定加载的dll名(无path,无后缀),这两种方法很坑爹,如要你利用Eclipse编辑工具时,你必须指定它的本机库位置(点击项目右键属性-》JAVA构造路径-》源代码下拉-》本地库位置-》编缉指定文件后搞定),否则你打死它它也说找不到DLL资源(反正我试了是没有行,也许我的RP值不够吧!),如果你指定了它的本机库位置了,先恭喜你,此时你运行在你的机子上确实成功了,但是,你不要高兴得早,试想,你在这是写死了的,那放到别的机子上,它还能跑起来吗,在这,我可以很负责任的告诉你,那是不行的,这样不是和我们的JAVA程序编译一次,到处跑相悖了吗,你读到这可能受不了,那我应怎么解决呢?你要相信,一个问题的产生肯定有它的解决方法,它的解决方法也许有上百种,你才用一两种就放弃了,那不是太可惜了,所以,接下来就是见证奇迹的时候了,具体方法如下:我在程序中的代码如下
public class HelloWorld {
--------------静态代码块就是动态的获取DLL,这样后你就跟上JAVA程序编译一次,到处跑的步伐了-------------------------------
static {
try {
String libpath = System.getProperty("java.library.path");
if (libpath == null || libpath.length() == 0) {
throw new RuntimeException("java.library.path is null");
}
String path = null;
StringTokenizer st = new StringTokenizer(libpath, System
.getProperty("path.separator"));
if (st.hasMoreElements()) {
path = st.nextToken();
} else {
throw new RuntimeException("can not split library path:"
+ libpath);
}
Class thisClass = HelloWorld.class;
InputStream inputStream = thisClass.getResource("HelloWorld.dll")
.openStream();
File dllFile = new File(new File(path), "HelloWorld.dll");
if (!dllFile.exists()) {
FileOutputStream outputStream = new FileOutputStream(dllFile);
byte[] array = new byte[8192];
for (int i = inputStream.read(array); i != -1; i = inputStream
.read(array)) {
outputStream.write(array, 0, i);
}
outputStream.close();
// System.loadLibrary("RegistryUtil");
}
System.loadLibrary("HelloWorld");//这样加载的DLL就不用去指定什么本机库位置了
} catch (UnsatisfiedLinkError e) {
throw e;
} catch (Throwable e) {
throw new RuntimeException("load RegistryUtil.dll error!", e);
}
}
public native void sayHello();// 表示要在c++本地实现的方法
public static void main(String[] args) {
new HelloWorld().sayHello();
}
}
接下来就是如何把DLL也打进JAR包里吧,其实so easy,你只要把整个项目都导出就可以了,这样你的JAR包里就有了DLL文件,此时就功德圆满了。