<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    gr8vyguy@Blogjava

    分析SWT3.3加載原生庫的過程


    SWT3.3 M4(2006年12月15日)新增加的功能之一是自動加載原生庫,特別是從SWT的Jar文件中加載原生庫的功能,大大方便了我們發布基于SWT的Java程序。SWT是怎么實現這個功能的呢?  理解其中的原理后,您也可以在您自己的程序中實現類似的功能。
    SWT負責加載原生庫的方法是Library類的loadLibrary (String name)
    static  {
        Library.loadLibrary( " swt " );
    }

    Library.loadLibrary()做的第一件事在庫名上加上版本號,比如swt-win32-3325。
    如果您的原生庫文件名不包含版本號,您可以省略這一步。

    String version = System.getProperty ("swt.version");
    if (version == null) {
    version = "" + MAJOR_VERSION;
    /* Force 3 digits in minor version number */
    if (MINOR_VERSION < 10) {
        version += "00"; //$NON-NLS-1$
        } else {
        if (MINOR_VERSION < 100) version += "0"; 
        }
        version += MINOR_VERSION;        
        /* No "r" until first revision */
    if (REVISION > 0) version += "r" + REVISION;
    }
    libName1 = name + "-" + Platform.PLATFORM + "-" + version;  
    libName2 = name + "-" + Platform.PLATFORM

    第二件事是加上操作系統相關的庫擴展名,比如Windows的.dll, Unix/Linux的.so.
    調用System.mapLibraryName (libName1).
    mappedName1  =  System.mapLibraryName (libName1);
    mappedName2  =  System.mapLibraryName (libName2);

    然后按順序從swt.library.path和java.library.path指定的目錄下尋找。如若沒有成功,
    并且沒有設置swt.library.path,那么再找一下java.io.tmpdir指定的目錄。要是還沒有成功,Library將嘗試
    將SWT的Jar文件中的原生庫解壓到swt.library.path目錄下或者java.io.tmpdir目錄下。
    /*  Try loading library from java library path  */
    f  (load (libName1))  return ;
    if  (mapName  &&  load (libName2))  return ;
        
    /*  Try loading library from the tmp directory  if swt library path is not specified  */
    if  (path  ==   null ) {
            path  =  System.getProperty ( " java.io.tmpdir " ); 
            path  =   new  File (path).getAbsolutePath ();
             if  (load (path  +  SEPARATOR  +  mappedName1))  return ;
             if  (mapName  &&  load (path  +  SEPARATOR  +  mappedName2))  return ;
    }
            
    /*  Try extracting and loading library from jar  */
    if  (path  !=   null ) {
             if  (extract (path  +  SEPARATOR  +  mappedName1, mappedName1))  return ;
             if  (mapName  &&  extract (path  +  SEPARATOR  +  mappedName2, mappedName2))  return ;
    }
        
    /*  Failed to find the library  */
    throw new UnsatisfiedLinkError ( " no  "   +  libName1  +   "  or  "   +  libName2 +   "  in swt.library.path, java.libary.path or the jar file " );


    extract (path+SEPARATOR+mappedName1, mappedName1)將mappedName1從Jar中解壓到
    path+SEPARATOR+mappedName1。最后如果還是沒有成功,甩出一個UnsatisfiedLinkError。


    整個過程有意思的只是extract()方法,下面來看看extract
    static   boolean  extract (String fileName, String mappedName)  {
        FileOutputStream os  =   null ;
        InputStream is  =   null ;
        File file  =   new  File(fileName);
         try   {
             if  ( ! file.exists ())  {
                is  =  Library. class .getResourceAsStream ( " / "   +  mappedName);
                 if  (is  !=   null )  {
                     int  read;
                     byte  [] buffer  =   new   byte  [ 4096 ];
                    os  =   new  FileOutputStream (fileName);
                     while  ((read  =  is.read (buffer))  !=   - 1 )  {
                        os.write(buffer,  0 , read);
                    }
                    os.close ();
                    is.close ();
                     if  ( ! Platform.PLATFORM.equals ( " win32 " ))  {
                         try   {
                            Runtime.getRuntime ().exec (
                    new  String [] { " chmod " ,  " 755 " , fileName} ).waitFor();
                        }   catch  (Throwable e)  {}
                    }
                     if  (load (fileName))  return   true ;
                }
            }
        }   catch  (Throwable e)  {
             try   {
                 if  (os  !=   null ) os.close ();
            }   catch  (IOException e1)  {}
             try   {
                 if  (is  !=   null ) is.close ();
            }   catch  (IOException e1)  {}
        }
         if  (file.exists ()) file.delete ();
         return   false ;
    }

    Library.class.getResourceAsStream ("/" + mappedName)返回指向Jar根目錄下mappedName文件的
    InputStream.個人感覺,extract寫得有點亂,if套著if,if套著try,當然并不是很糟糕,本身這是一個比較簡單的函數。
    在我自己的程序中,重寫了extract(改名為extractAndLoad),相對來說要清爽一些,請大家比較。 
    通過上面的分析,我們可以很簡單實現我們自己的loadLibrary
    import  org.eclipse.swt.SWT;

    import  java.io.File;
    import  java.io.FileOutputStream;
    import  java.io.InputStream;

    /**
     * The method loadLibrary load a native library in the order 
     * from java.library.path, os.library.path, tmpdir and from jar.
     *  
     *  @author  pan
      */
    public   class  Library {

         static   final  String SEPARATOR  =  System.getProperty( " file.separator " );

         public   static   void  loadLibrary(String name) {
             //  Try loading library from os library path
            String path  =  System.getProperty( " os.library.path " );
             if  (path  !=   null ) {
                path  =   new  File(path).getAbsolutePath();
                 if  (_load(System.mapLibraryName(path  +  SEPARATOR  +  name)))
                     return ;
            }

             //  Try loading library from java library path
             if  (_load(name))
                 return ;

             //  Try loading library from the tmp directory if os library path is not specified
             if  (path  ==   null ) {
                path  =  System.getProperty( " java.io.tmpdir " );
                path  =   new  File(path).getAbsolutePath();
                 if  (_load(System.mapLibraryName(path  +  SEPARATOR  +  name)))
                     return ;
            }

             //  Try extracting and loading library from jar
             if  (path  !=   null
                     &&  loadFromJar(System.mapLibraryName(path  +  SEPARATOR  +  name),
                            System.mapLibraryName(name)))
                 return ;

             //  Failed to find the library
             throw   new  UnsatisfiedLinkError( " no  "   +  name
                     +   "  in java.libary.path, os.library.path or jar file " );
        }

         private   static   boolean  _load(String libName) {
             try  {
                 if  (libName.indexOf(SEPARATOR)  !=   - 1 ) {
                    System.load(libName);
                }  else  {
                    System.loadLibrary(libName);
                }
                 return   true ;
            }  catch  (UnsatisfiedLinkError e) {
            }
             return   false ;
        }

         private   static   boolean  loadFromJar(String outFileName, String libName) {
             try  {
                 return  extractAndLoad(outFileName, libName);
            }  catch  (Throwable e) {
            }
             return   false ;
        }

         private   static   boolean  extractAndLoad(String outFileName, String libName)
                 throws  Throwable {
             int  read;
             byte [] buf  =   new   byte [ 4096 ];
            InputStream is  =   null ;
            FileOutputStream os  =   null ;

            File file  =   new  File(outFileName);
             if  (file.exists())
                file.delete();

             if  ( ! file.exists()) {
                 try  {
                    os  =   new  FileOutputStream(file);
                    is  =  Library. class .getResourceAsStream( " / "   +  libName);
                     if  (is  ==   null   ||  os  ==   null )
                         return   false ;

                     while  ((read  =  is.read(buf))  !=   - 1 )
                        os.write(buf,  0 , read);
                }  finally  {
                     if  (os  !=   null )
                        os.close();
                     if  (is  !=   null )
                        is.close();
                }

                 if  ( ! SWT.getPlatform().equals( " win32 " )) {
                    Runtime.getRuntime().exec(
                             new  String[] {  " chmod " ,  " 755 " , outFileName }).waitFor();
                }

                 return  _load(outFileName);
            }

             return   false ;
        }
    }

    然后把您的原生庫打在Jar里面,用Library.loadLibrary加載原生庫,而不是System.loadLibrary,這樣您就
    把原生庫隱藏在您的Jar里面了。

    轉載請保留http://www.tkk7.com/xilaile/archive/2007/03/23/105706.html

    posted on 2007-03-23 02:10 gr8vyguy 閱讀(5469) 評論(1)  編輯  收藏 所屬分類: Java

    評論

    # re: 分析SWT3.3加載原生庫的過程 2007-03-23 02:51 BeanSoft

    就是先解壓在系統臨時目錄里了, 然后再加載. 有時候會有問題, 例如你的 dll 需要相對路徑的時候就不能用這種方法了, 倒是可以解壓縮在一個固定的相對位置, 退出時清空.

    不過 SWT 這個新特性的確是人性化的多了... 做軟件多考慮用戶, 是王道啊...  回復  更多評論   

    <2007年3月>
    25262728123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導航

    統計

    公告

  • 轉載請注明出處.
  • msn: gr8vyguy at live.com
  • 常用鏈接

    留言簿(9)

    隨筆分類(68)

    隨筆檔案(80)

    文章分類(1)

    My Open Source Projects

    搜索

    積分與排名

    最新評論

    主站蜘蛛池模板: 免费少妇a级毛片| 亚洲视频小说图片| 久久成人无码国产免费播放| 亚洲一二成人精品区| 成人黄18免费视频| 99久久免费国产精精品| 亚洲最新在线视频| 免费人妻av无码专区| 久久久高清日本道免费观看| 亚洲色大成网站WWW国产| 亚洲人精品午夜射精日韩| 免费影院未满十八勿进网站| 一级做性色a爰片久久毛片免费| 亚洲色欲www综合网| 亚洲日韩在线观看免费视频| 亚洲免费在线观看视频| 成年免费a级毛片| 亚洲一区二区三区在线观看蜜桃| 亚洲午夜激情视频| 九九九精品成人免费视频| 3344在线看片免费| 美女啪啪网站又黄又免费| 亚洲天堂福利视频| 国产成人精品日本亚洲网站| 国产成人免费福利网站| 久久免费看黄a级毛片| 中文字幕乱码系列免费| 国产精品国产亚洲区艳妇糸列短篇| 亚洲男人都懂得羞羞网站| 亚洲综合久久夜AV | 成人免费视频软件网站| 在免费jizzjizz在线播| a级毛片免费高清毛片视频| 亚洲AV成人无码网站| 亚洲精品中文字幕麻豆| 亚洲乱码精品久久久久..| 国产高清免费观看| 欧美在线看片A免费观看| 日韩插啊免费视频在线观看 | 日韩高清在线免费看| 日本人的色道免费网站|