熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> JSP教程 >> 正文

運用JNA保護你的遺留代碼(二)

2013-11-15 09:49:47  來源: JSP教程 

  從Java中引用DLL代碼

  列表四演示代碼引用DLL函數

         public interface CLibrary extends Library {

  CLibrary INSTANCE = (CLibrary)

  NativeloadLibrary((PlatformisWindows() ? nativecode : c)

  CLibraryclass);

  int helloWorld(int divider);

  }

  public static void main(String[] args) {

  CLibraryINSTANCEhelloWorld());

  }

  列表四訪問DLL函數

  在列表四中CLibrary實例被創建這個對象允許指定的DLL被下載接下來是庫的裝入過程標志需要從庫中標記——在列表四的實例中只有一個標志被稱為helloWorld()

  列表五演示的程序來自列表四的代碼

        C:\jnacode>java HelloWorld

  Value is

  列表五調用的DLL的代碼

  在列表五中沒有什麼好驚奇的——值獲准進入函數緊接著在函數內部參數()被得出答案

  當我嘗試著著手解決DLL的問題與調用約定聯系起來我想看看生成DLL的過程幸運的是你可以通過一種工具實現這個願望這個工具被稱為Dependency Walker通過Dependency Walker你可以看到DLL的生成過程為了實現你需要下載一個免費的Dependency Walker副本打開然後把DLL裝載在裡面你就可以看見如圖一所示的類似內容

  運用JNA保護你的遺留代碼(二)

  圖一DLL內部信息

  注意圖一中的函數名稱這些函數名稱與DLL標志helloWorld()相匹配如果當你創建一個DLL的時候使用標准調用約定函數名稱將會如圖所示

  運用JNA保護你的遺留代碼(二)

  圖標准調用約定

  注意函數名稱變化的方式現在如果你嘗試運行Java程序將會得到令人厭煩的錯誤提示如列表六所示

         C:\jnacode>java HelloWorld

  Exception in thread main javalangUnsatisfiedLinkError: Error looking up function helloWorld: The specified procedure could not be found

  at comsunjnaFunction(Functionjava:)

  at comsunjnaNativeLibrarygetFunction(NativeLibraryjava:)

  at comsunjnaLibrary$Handlerinvoke(Libraryjava:)

  at $ProxyhelloWorld(Unknown Source)

  at HelloWorldmain(HelloWorldjava:)

  列表六連接器錯誤

  包括上面的錯誤情況因為我自己也突然遇到了以上情形所以這是一個完全的JNA現場演示案例這與JNI是如何聯系的——JNA的前身?

  JNI不是今天謝謝!

  我經常想到這些年來JNI承受了很多評論在很多實例中一個軟件支持部門要做的第一件事情就是說你使用JNI嗎?如果答案是肯定的然後在很多例子中沒有接踵而來的支持另一方面在很多顧問工作中我看見很多JNI案例這些JNI案例在大型Java和C++代碼基礎之間使用在這樣一種情況中Java和C++通過所有的單元結合測試但是生產出來的代碼隨時有崩潰的可能性這種情況下Java和C++程序員嘗試著掩飾這種情況每個人都在指責對方

  解決JNI的悲哀的一個比較好的方案是通過一系列清單項目運行這些在任何一邊的清單項目都是為了代碼舉個例子在C這邊的代碼

  · 一個數組邊界被突破?

  · 一個空指針被取消引用?

  · 動態內存被正確的分配?

  JNA有可能結束這種類型情況

  庫許可問題?

  JNA令人感興趣的是它開啟了Java直接存儲DLL代碼的功能它也適用於其它的庫技術比如共享的Unix庫軟件組成部分得到許可的意思是什麼?JNA的使用也許是令人信服的可以用來存取Java中的許可的庫代碼另一方面是JNA代碼可以允許存取安全限制庫代碼

  除了上面所考慮的問題具有存取遺留代碼的能力也是很重要的現在讓我們來看一看

  當遺留代碼調用通過JNA報錯時

  回顧列表三中的代碼除一個參數使之成為一個不變值如果我把設置為除數執行操作的時候會發生什麼那?

         public interface CLibrary extends Library {

  CLibrary INSTANCE = (CLibrary)

  NativeloadLibrary((PlatformisWindows() ? nativecode : c)

  CLibraryclass);

  int helloWorld(int divider);

  }

  public static void main(String[] args) {

  CLibraryINSTANCEhelloWorld());

  Systemoutprintln(Value: + CLibraryINSTANCEhelloWorld());

  }

  列表設置為除數的情況

  當我執行列表七中的代碼我將會得到如列表八所示的輸出示意

         C:\jna_article\jnacode>java HelloWorld

  Value is

  #

  # An unexpected error has been detected by HotSpot Virtual Machine:

  #

  # EXCEPTION_INT_DIVIDE_BY_ZERO (xc) at pc=xb pid= tid=

  

  #

  # Java VM: Java HotSpot(TM) Client VM (_b mixed mode)

  # Problematic frame:

  # C [nativecodedll+x]

  #

  # An error report file with more information is saved as hs_err_pidlog

  #

  # If you would like to submit a bug report please visit:

  #

  列表障礙除數為的意外情況

  這可不漂亮但是我們還是得到了一些結果無論如何在現實生活中是線性增長的例子想像一下嘗試在一個大的代碼庫中查找的狀況總的來說JNA是很強大的但是就像任何強大的事情一樣它還需要責任感

  運行提供的代碼以及CLASSPATH事務

  伴隨著JNA對此進行安排並且運行並不是十分困難——確認你跟隨了一些簡單的指導方針我已經實現了自己定制的DLL並且編輯Java代碼作為源代碼的一部分Zip文件你需要確定這些代碼可以在Windows XP上面運行不需要編輯其它什麼部件

  運行代碼解壓源文件到一個文件夾比如C:\jnacode接下來的步驟是可選擇的因為源文件包含一個jnajar 副本如果你打算擁有自己的jnajar 副本或者一個新的發布版本然後再下載jnajar文件的副本為了使事情更為簡單將jnajar文件放到上面的文件夾中然後確認jnajar和包含文件夾都在CLASSPATH中接下來你可以嘗試運行HelloWorld類

  如果你感到充滿了刺激或者活力你也許會喜歡嘗試著創建你自己的DLL就像是我們在前面所描述的只需要按照上面所描述的做你能做的很好以防萬一如果你遇到任何問題你都可以拜訪JNA站點

  結論JNA是如何一步步走來的?

  我很喜歡JNA它非常的易於使用如果你的庫代碼是使用正確的方法編輯的你就不會遇到很多繁瑣的問題JNA即將成為非常有用的工具來組織處理大量的復雜的工作關鍵業務遺留代碼不再有厭煩的JNI標記並且頭文件可以自動生成

  有一點非常重要與任何新技術相比是非常容易把人們帶進麻煩中的任何JNA都不例外因為這個原因如果JNA有條不紊的使用它將必定會超越JNI以及那些昂貴的私有的橋接機制什麼樣的形式可能會采取這樣的規則?JNA資源中的任何調用(比如庫代碼)將會被充分的記錄提供審查索引面向方面的技術建議自己使用這種方案比如說EJB攔截裝置將會被用於確定JNA代碼記錄的效果

  另外任何數據獲准進入本地庫(通過JNA代碼)將會被認真的檢查我猜想JNA成功的關鍵就是操作進行的緩慢而認真


From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19189.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.