• jni中关于dll的装载问题[转]


       通常我们在写大型项目时,也就是集成的项目时,单独用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文件,此时就功德圆满了。

  • 相关阅读:
    Linux基础之文件管理(高级)上等相关内容-96
    Linux基础之文件管理(基础)等相关内容-95
    Linux基础之初识shell之系统命令基础等相关内容-94
    Linux基础之操作系统启动流程等相关内容-93
    人常犯的三种愚蠢
    数据挖掘科学家
    记住
    但行好事,莫问前程
    记住发生在身上的事,不要小心眼--活的明白
    语言要简洁
  • 原文地址:https://www.cnblogs.com/spinsoft/p/2628415.html
Copyright © 2020-2023  润新知