[轉摘]使用IKVM在C#中調用JAVA程序


IKVM.NET是一個針對Mono和微軟.net框架的java實現,其設計目的是在.NET平台上運行java程序。本文將比較詳細的介紹這個工具的原理、使用入門(如何java應用轉換為.NET應用、),希望能給大家帶來驚喜。

 

一、介紹


IKVM.NET是一個針對Mono和微軟.NET框架的java實現,其設計目的是在.NET平台上運行java程序。它包含了以下的組件:
一個用.NET實現的java虛擬機。
一個java類庫的.NET實現。
致力於在java和.NET之間交互的工具。

 

二、IKVM.NET的組件


IKVM.NET包含以下的部分:
IKVM.Runtime.dll VM運行時和所有支持代碼。它包括以下的功能:
Byte Code JIT 編譯器和驗證器,使用JIT將Java Byte Code編譯為CIL(C中間語言)。
對象模式映射結構,將.NET中的System.Object,System.String,System.Exception映射為JAVA代碼中的java.lang.Object, java.lang.String,java.lang.Throwable。
管理本地方法(在Classpath中)的.NET重新實現。
IKVM.GNU.Classpath.dll 被編譯的GNU Classpath版本,它是由自由軟件基金會實現的JAVA類庫和一些IKVM.NET附加代碼組成的。注意:這里的GNU Classpath不是IKVM.NET的一部分,但是前者被用在IKVM.NET中。
IKVM.JNI.dll 通過實現JNI接口管理C++匯編。作為一個可選部分,只在程序使用自己的本地庫時才被用到。而對於純JAVA程序來講是不會被用到的。
ikvm.exe 與java.exe很類似的啟動執行程序(動態模式)。
ikvmc.exe 靜態編譯器,被用來編譯java類和jar使其成為.NET匯編(靜態模式)。
ikvmstub.exe 一個從.NET匯編生成存根類的工具,就如javap一樣反編譯.NET匯編。IKVM.NET了解如何存根並用實際的.NET類型引用替換對存根的引用。
IKVM.AWT.WinForms.dll 非常有限的零散AWT實現。

三、IKVM原理


1.如何替換JVM
IKVM應用包含了采用.NET實現的java虛擬機。在一些場合,我們可以用它替換掉java。例如: java -jar myapp.jar 將被替換為 ikvm -jar myapp.jar。
2.在.NET應用中使用java類庫
IKVM.NET包含ikvmc,這個在java bytecode與.NET中間語言的轉換器。如果我們使用一個被用在.NET平台的java庫的話, 運行ikvmc –targetlibrary mylib.jar(mylib.jar在這里指代我們的jar文件)來生成mylib.dll。例如apache FOP項目是一個開源的XSL-FO處理器項目,它使用java語言編寫的用於從xml生成PDF文檔。使用IKVM.NET技術,我們可以將apache FOP用在任何的.NET應用中。這樣在開發.NET應用的同時利用IKVM便可以使用java開源項目這個免費的軟件倉庫。盡管在IKVM.NET沒有提供在.NET中使用的java編譯器,但是我們可用開源的Jikes編譯器將java源代碼編譯為JVM bytecode,然后使用ikvmc –targetexe myapp.jar來生產.NET執行文件。我們甚至可以通過包含ikvmstub應用的方式在我們的java代碼中用.NET API。

四 語法(譯者注:這個工具是在windows命令提示窗中使用的)


ikvmc [ options ] classOrJarfile [ classOrJarfile ... ]

參數見下:
類文件(.class)或包文件(.jar)
Java類或包文件的名字可以含有通配符(如*.class)。


參數----參數說明

-out:輸出文件----指定輸出文件的文件名。文件名應含有擴展名.dll(參數-target設為library時)或.exe(參數-target設為exe或winexe時)。一般地,缺省狀態下ikvmc會根據輸入文件名和-target參數來確定輸出文件名。但是,如果在輸入文件名中使用了通配符,那么就必須使用這個選項來指定輸出文件名。

-assembly:程序集名稱----指定生成的程序集名稱。一般地,缺省狀態下,程序集名就是輸出文件名。

-target:目標類型----指定生成目標.exe或.dll文件的類型,可以指定如下值:
exe——生成一個在windows命令窗口中運行的可執行程序。
winexe——生成一個帶有界面的.exe應用程序。
library——生成一個動態鏈接庫(.dll)文件。
module——生成一個.net模塊。


在Linux平台上,exe與winexe兩個參數是沒有區別的。

-keyfile:主文件名----主文件名用於指定結果程序集。

-version:M.m.b.r ----指定程序集版本。

-main:類名----指定含有main函數的類的名稱。缺省情況下,如果-target參數設置為exe或winexe,ikvmc會搜尋合法的main函數,在找到的情況下會給用戶提示。

-reference:----指定類庫位置 。 如果Java代碼使用了.NET的編程接口(API),那么使用這個選項指定這些動態鏈接庫(dll)。如果引用了不止一個類庫文件,那么此選項可以多次使用。可以使用通配符(例如:c:\libs\*.dll)。

- recurse:filespec---- 處理當前文件夾下所有可與filespec匹配的文件。例如:- recurse: *.class

-nojni----對於非Java函數(native methods)不要生成用於非Java代碼的Java接口(JNI)。

-resource:路徑名----指定Java資源的引用路徑名。

-exclude:文件名---- 要排除的類名列表。

-debug----將調試信息輸出。注意:只有當.class文件含有調試信息(即使用javac-g參數編譯)時才有用。

-srcpath:路徑----指定源代碼的位置。與-debug同時使用。程序會將包中類的搜索路徑指定為此路徑,並從中搜索類的源代碼。

-Xtrace:名稱---- 顯示所有該指定名稱的跟蹤點。

-Xmethodtrace:函數名 ---- 指定的生成的函數名,將函數跟蹤器(method trace)生成到此函數中。

幾點說明:
ikvmc利用Java類文件和包文件生成.NET程序集。它將輸入文件中的Java二進行代碼轉化成.NET公共中間語言(CIL)。並利用它來生成:
.NET可執行文件(-target:exe or –target:winexe)
.NET類庫(-target:library)
.NET模塊(-target:module)
Java程序一般由一系列的包文件組成。ikvmc可以將多個包文件(和類文件)轉化成一個單獨的.NET可執行程序或類庫文件。例如,一個程序包含main.jar、lib1.jar和lib2.jar可以轉化成一個單獨的main.exe文件。
處理多個包文件時,如果有多個相同的類或源文件,ikvmc會使用第一個讀入的版本,而忽略以后讀到的。這時會產生警告信息。因此,包文件的順序至關重要。
注意:
為了得到最佳結果,使用ikvmc轉換Java程序時,請按照Java程序中類路徑的順序在,把要轉換包的列表鍵入ikvmc的命令行。

 

五 使用入門


1.    到IKVM官方網站下載IKVM需要的組件 1) ikvm-0.40.0.1.zip ;2)ikvmbin-0.40.0.1.zip ;3)openjdk6-b12-stripped.zip
2.    解壓ikvm-0.40.0.1.zip,並將%IKVM_HOME%\bin添加到path中。此處的%IKVM_HOME%是指解壓后ikvm的主目錄。
3.    到Debian IKVM下載IKVM.OpenJDK.ClassLibrary.dll。 或者到rayfile去下載data.tar.gz。這個文件可以直接用winrar解壓。
4.    你需要下載一個簡單的工具undeb去解壓.deb文件。
5.    解壓ikvm_0.38.0.2+dfsg-2_all.deb文件。
6.    新建一個Java文件, 如

   1: package myPackage;
   2: public class Hello
   3:  {
   4:     public String sayHello()
   5:     {
   6:         String str = "Hello, this String is from java program.";
   7:         return str;
   8:     }
   9: }

7.   編譯Hello.java文件,然后將myPackage打包成一個jar文件,例如jar cvf myJava.jar myPackage

8.   使用ikvmc -out:myJava.dll myJava.jar。你現在應該在看到一個myJava.dll文件。亦可以在轉換時指定結果程序集 如: ikvmc -target:library myJava.jar - keyfile:key.snk

9.   新建一個C#.NET項目,首先添加一下必須的DLL。

1) %IKVM_HOME%\bin\IKVM.OpenJDK.Core.dll;
2) %IKVM_HOME%\bin\IKVM.Runtime.dll ;
3) %IKVM_HOME% \bin\IKVM.Runtime.JNI.dll ; ( IKVM.OpenJDK.ClassLibrary.dll[這的DLL在ikvm_0.38.0.2+dfsg-2_all.deb\usr\lib\cli文件夾中。或者也可在data.tar.gz中的usr\lib\cli中找到)

10.   添加第8步生成的myJava.dll到C#.NET項目中,然后using %package_name%就可以實現對Java的調用。

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Drawing;
   4: using System.Windows.Forms;
   5:  
   6: using myPackage;
   7: namespace testIkvm
   8: {
   9:     public partial class frmTest: Form
  10:     {
  11:         private void btnTestJar_Click(object sender, EventArgs e)
  12:         {
  13:             Hello h1 = new Hello();
  14:             String s1 = h1.sayHello();
  15:             tbTest.Text = s1;
  16:         }
  17:     }
  18: }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM