程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 運用JNA保護你的遺留代碼(二)

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

編輯:關於JAVA

從Java中引用DLL代碼

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

public interface CLibrary extends Library {
  CLibrary INSTANCE1 = (CLibrary)
  Native.loadLibrary((Platform.isWindows() ? "nativecode" : "c"),
   CLibrary.class);
  int helloWorld(int divider);
  }
  public static void main(String[] args) {
  CLibrary.INSTANCE1.helloWorld(77));
  }

列表四,訪問DLL函數

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

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

C:\jnacode>java HelloWorld
  Value is 1

列表五,調用的DLL的代碼

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

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

圖一,DLL內部信息

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

圖2,標准調用約定

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

C:\jnacode>java HelloWorld
  Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'helloWorld': The specified procedure could not be found.
  at com.sun.jna.Function. (Function.java:129)
  at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:250)
  at com.sun.jna.Library$Handler.invoke(Library.java:191)
  at $Proxy0.helloWorld(Unknown Source)
  at HelloWorld.main(HelloWorld.java:31)

列表六,連接器錯誤

包括上面的錯誤情況,因為我自己也突然遇到了以上情形。所以,這是一個完全的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報錯時

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

public interface CLibrary extends Library {
  CLibrary INSTANCE1 = (CLibrary)
  Native.loadLibrary((Platform.isWindows() ? "nativecode" : "c"),
   CLibrary.class);
  int helloWorld(int divider);
  }
  public static void main(String[] args) {
  CLibrary.INSTANCE1.helloWorld(77));
  System.out.println ("Value: " + CLibrary.INSTANCE1.helloWorld(0));
  }

列表7把0設置為除數的情況

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

C:\jna_article\jnacode>java HelloWorld
  Value is 1
  #
  # An unexpected error has been detected by HotSpot Virtual Machine:
  #
  # EXCEPTION_INT_DIVIDE_BY_ZERO (0xc0000094) at pc=0x009b1365, pid=1768, tid=458
  4
   #
  # Java VM: Java HotSpot(TM) Client VM (1.5.0_17-b04 mixed mode)
  # Problematic frame:
  # C [nativecode.dll+0x11365]
  #
  # An error report file with more information is saved as hs_err_pid1768.log
  #
  # If you would like to submit a bug report, please visit:
  # http://java.sun.com/webapps/bugreport/crash.jsp

列表8,障礙:除數為0的意外情況

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

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

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

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

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

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

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

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

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved