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

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

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

    gr8vyguy@Blogjava

    分析SWT3.3加載原生庫(kù)的過(guò)程


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

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

    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

    第二件事是加上操作系統(tǒng)相關(guān)的庫(kù)擴(kuò)展名,比如Windows的.dll, Unix/Linux的.so.
    調(diào)用System.mapLibraryName (libName1).
    mappedName1  =  System.mapLibraryName (libName1);
    mappedName2  =  System.mapLibraryName (libName2);

    然后按順序從swt.library.path和java.library.path指定的目錄下尋找。如若沒(méi)有成功,
    并且沒(méi)有設(shè)置swt.library.path,那么再找一下java.io.tmpdir指定的目錄。要是還沒(méi)有成功,Library將嘗試
    將SWT的Jar文件中的原生庫(kù)解壓到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。最后如果還是沒(méi)有成功,甩出一個(gè)UnsatisfiedLinkError。


    整個(gè)過(guò)程有意思的只是extract()方法,下面來(lái)看看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.個(gè)人感覺(jué),extract寫得有點(diǎn)亂,if套著if,if套著try,當(dāng)然并不是很糟糕,本身這是一個(gè)比較簡(jiǎn)單的函數(shù)。
    在我自己的程序中,重寫了extract(改名為extractAndLoad),相對(duì)來(lái)說(shuō)要清爽一些,請(qǐng)大家比較。 
    通過(guò)上面的分析,我們可以很簡(jiǎn)單實(shí)現(xiàn)我們自己的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 ;
        }
    }

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

    轉(zhuǎn)載請(qǐng)保留http://m.tkk7.com/xilaile/archive/2007/03/23/105706.html

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

    評(píng)論

    # re: 分析SWT3.3加載原生庫(kù)的過(guò)程 2007-03-23 02:51 BeanSoft

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

    不過(guò) SWT 這個(gè)新特性的確是人性化的多了... 做軟件多考慮用戶, 是王道啊...  回復(fù)  更多評(píng)論   

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

    導(dǎo)航

    統(tǒng)計(jì)

    公告

  • 轉(zhuǎn)載請(qǐng)注明出處.
  • msn: gr8vyguy at live.com
  • 常用鏈接

    留言簿(9)

    隨筆分類(68)

    隨筆檔案(80)

    文章分類(1)

    My Open Source Projects

    搜索

    積分與排名

    最新評(píng)論

    主站蜘蛛池模板: 亚洲国产午夜中文字幕精品黄网站 | 永久看日本大片免费35分钟| 亚洲香蕉成人AV网站在线观看 | 亚洲黄黄黄网站在线观看| 亚洲av永久无码| 免费高清av一区二区三区| 亚洲国产成人久久精品大牛影视 | 亚洲第一成年网站大全亚洲| aⅴ免费在线观看| 蜜芽亚洲av无码精品色午夜| 51视频精品全部免费最新| 久久久久亚洲精品无码蜜桃| 91成人在线免费视频| 亚洲成人在线免费观看| 国产一卡2卡3卡4卡2021免费观看 国产一卡2卡3卡4卡无卡免费视频 | 日韩精品免费一级视频| 亚洲综合久久成人69| 亚洲中文无码永久免费 | 日本人成在线视频免费播放| 亚洲AV成人无码久久精品老人| 一级毛片aaaaaa免费看| 亚洲视频一区在线| 美女视频黄免费亚洲| 蜜桃传媒一区二区亚洲AV| 亚洲A∨午夜成人片精品网站| 一级免费黄色毛片| 国产∨亚洲V天堂无码久久久| 污视频在线观看免费| 亚洲国产精品综合久久2007| 久久不见久久见中文字幕免费| 狠狠综合亚洲综合亚洲色| xvideos亚洲永久网址| 中国精品一级毛片免费播放| 亚洲天堂中文字幕| 成年免费大片黄在线观看岛国| 亚洲国产成人精品无码区花野真一| 免费人成在线观看视频播放| 久草免费福利在线| 亚洲美女自拍视频| 最好免费观看韩国+日本| 五级黄18以上免费看|