JCOBridge สร้างขึ้นจากปลั๊กอิน DLR ที่ได้รับการพิสูจน์แล้วซึ่งมีอยู่ในแพลตฟอร์ม Sinapse รับประกันประสิทธิภาพที่ดีที่สุดในการรวม JVM และ CLR ของโลก
- ดึงข้อมูลประเภท CLR
- สร้างอินสแตนซ์วัตถุ CLR
- เรียกใช้วิธีการแบบคงที่
- เรียกใช้วิธีการอินสแตนซ์
- รับ/ตั้งค่าคุณสมบัติคงที่
- รับ/ตั้งค่าคุณสมบัติอินสแตนซ์
- ตั้งค่าผู้ได้รับมอบหมาย
- สมัครสมาชิก / ยกเลิกการสมัครกิจกรรม
- รวมการควบคุม WPF เข้ากับหน้าต่าง AWT/Swing
- รวมการควบคุม WinForms เข้ากับหน้าต่าง AWT/Swing
- รวมออบเจ็กต์อินเทอร์เฟซผู้ใช้แบบกราฟิก .NET ที่ซับซ้อนเข้ากับหน้าต่าง AWT/Swing
- การควบคุมส่วนติดต่อผู้ใช้ คุณสมบัติ และการจัดการเหตุการณ์
- ดึงข้อมูลคลาส JVM
- สร้างอินสแตนซ์อ็อบเจ็กต์ JVM
- เรียกใช้วิธีการแบบคงที่
- เรียกใช้วิธีการอินสแตนซ์
- รับ/ตั้งค่าฟิลด์คงที่
- รับ/ตั้งค่าฟิลด์อินสแตนซ์
- ใช้การเข้าถึงแบบไดนามิกเพื่อเขียนโค้ดได้อย่างราบรื่นเหมือนกับที่ทำในภาษา Java
- ใช้อินเทอร์เฟซเฉพาะเพื่อควบคุมวิธีการและฟิลด์ต่างๆ
JCOBridge (JVM-CLR Object Bridge) อนุญาตให้เรียกใช้งานภาษาพื้นเมืองของ JVM เช่น java และ scala จากภาษา CLR/.NET และในทางกลับกัน อนุญาตให้นำเข้าและใช้ไลบรารี ส่วนประกอบ และยังจัดการส่วนต่อประสานผู้ใช้แบบกราฟิกจากที่เดียว การเขียนโปรแกรมโลกไปยังอีกโลกหนึ่ง ข้อมูลเพิ่มเติมเกี่ยวกับ www.jcobridge.com
หากต้องการสำรวจตัวอย่าง คุณต้องทำตามขั้นตอนต่อไปนี้:
ในที่เก็บนี้ คุณสามารถค้นหาโค้ดตัวอย่างสำหรับภาษาการเขียนโปรแกรมอื่นที่ JCObridge รองรับ ตัวอย่างถูกจัดระเบียบในสองโฟลเดอร์หลัก JVM และ CLR ที่มีโปรเจ็กต์ที่เกี่ยวข้อง ก่อนที่จะดำเนินการโค้ดนั้นจำเป็นต้องรวบรวมตัวอย่างของทั้งสองโลก เนื่องจากไม่มีการคอมไพล์โค้ดต่างประเทศแบบรันไทม์ มีเพียงการดำเนินการเท่านั้น
GUI ข้ามแพลตฟอร์มของโปรเจ็กต์แสดงวิธีใช้ AWT เพื่อสร้างอินเทอร์เฟซผู้ใช้แบบกราฟิกข้ามแพลตฟอร์มสำหรับ .NET Core บนโฮสต์ Windows และ Linux หากต้องการใช้ Swing เพียงเปลี่ยนการควบคุมภายในโค้ดเป็นตัวควบคุมที่คุณต้องการ
นี่คือตัวอย่างพื้นฐานที่เราเรียกคลาสแบบง่ายที่กำหนดใน JavaClass.java จากแอปพลิเคชัน .NET ใน /JVM/java/src/JavaClass.java เรามีคลาสที่เรียบง่าย
public class JavaClass {
/**
* This simple method return the "Hello World!!" string
* * @return "Hello World!!" string
*/
public String helloWorld ()
{
return "Hello World from Java!!" ;
}
/**
* This simple method return the sum of two double
* @param a
* @param b
* @return a + b
*/
public double add ( double a , double b )
{
return a + b ;
}
/**
* This simple method return the sin of a double
* @param a
* @return sin of a
*/
public double sin ( double a )
{
return Math . sin ( a );
}
}
ใน CLRJavaClassUseExampleprogram.cs เรามีแอปพลิเคชัน .NET C# อย่างง่าย
using MASES . LicenseManager . Common ;
using MASES . JCBridge . C2JBridge ;
using System ;
namespace JavaClassUseExample
{
class Program
{
static void Main ( string [ ] args )
{
new TestClass ( ) . Execute ( ) ;
}
class TestClass : SetupJVMWrapper
{
public override string ClassPath { get { return @"....JVMOutput" ; } }
public void Execute ( )
{
double a = 2 ;
double b = 3 ;
double c = Math . PI / 2 ;
var javaClass = DynJVM . JavaClass . @new ( ) ;
string hello = javaClass . helloWorld ( ) ;
double result = javaClass . add ( a , b ) ;
double sin = javaClass . sin ( c ) ;
Console . WriteLine ( "{0} {1} + {2} = {3} and sin({4:0.0000000}) = {5:0.00000000}" , hello , a , b , result , c , sin ) ;
}
}
}
}
การรันโค้ดเราจะได้ผลลัพธ์ดังนี้:
Hello World from Java!! 2 + 3 = 5 and sin(3,1415927) = 1,00000000
ตัวอย่างนี้เป็นส่วนขยายของ ตัวอย่างการใช้คลาส Java โดยมีการกำหนดค่าพารามิเตอร์สภาพแวดล้อมในคลาส .NET TestClass
class TestClass : SetupJVMWrapper
{
// the following line setup the classpath where JVM will search for classes
// during runtime it is possible to dynamically add other path using a call like DynJVM.JVMHelper.addPath(<the path to add>);
public override string ClassPath { get { return @"C:Program FilesMASES GroupJCOBCore;....JVMJavaOutput" ; } }
// uncomment the following line and set the correct JRE if the automatic search system fails
// public override string JVMPath { get { return @"C:Program FilesJavajre1.8.0_121binserverjvm.dll"; } }
// the following code adds all possible switch to the starting JVM.
// for a complete list see Oracle documentation: https://docs.oracle.com/javase/8/docs/technotes/tools/windows/java.html
public override IEnumerable < KeyValuePair < string , string > > JVMOptions
{
get
{
var dict = new Dictionary < string , string > ( ) ;
dict . Add ( "-Xmx128M" , null ) ; // this line adds a complete argument
// dict.Add(property, value); // this line adds an argument like -Dproperty = value
return dict ;
}
}
// the following code adds initial packages to the import statement.
public override IEnumerable < string > JVMPackages
{
get
{
var list = new List < string > ( ) ;
list . Add ( "java.lang" ) ; // this line adds java.lang.* like you do with "import java.lang.*" in Java
return list ;
}
}
// uncomment and set the following line when you need features of JDK like the use of the compiler
// public override string JDKHome { get { return @"C:Program FilesJavajdk1.8.0_121"; } }
public void Execute ( )
{
double a = 2 ;
double b = 3 ;
double c = Math . PI / 2 ;
var javaClass = DynJVM . JavaClass . @new ( ) ;
string hello = javaClass . helloWorld ( ) ;
double result = javaClass . add ( a , b ) ;
double sin = javaClass . sin ( c ) ;
Console . WriteLine ( "{0} {1} + {2} = {3} and sin({4:0.0000000}) = {5:0.00000000}" , hello , a , b , result , c , sin ) ;
Console . WriteLine ( "Press Enter to exit" ) ;
Console . ReadLine ( ) ;
}
}
นี่เป็นแอปพลิเคชั่นที่ซับซ้อนมากขึ้นที่สำรวจความสามารถของ JCOBridge ในการดำเนินการต่อไปนี้: - เรียกใช้โค้ด java ในสภาพแวดล้อม .NET โดยใช้ Dynamic JVM wrapper - จัดการวัตถุที่ใช้ร่วมกัน - ลงทะเบียนวัตถุ CLR ในฝั่ง Java Virtual Machine - ใช้วัตถุที่ลงทะเบียน จากด้าน JVM - วิธีการเรียกบนคลาสที่ลงทะเบียน JVM และมีการดำเนินการสะท้อนไปยังวัตถุ CLR - สร้างกล่องโต้ตอบในด้าน JVM และใช้จากรหัส .NET
ไลบรารีนี้มีคลาสเดียวที่ให้การดำเนินการแบบ double และ string ที่จะเรียกจาก JVM
แผง Windows Form พร้อมตรรกะที่สมบูรณ์ซึ่งจะใช้ในการสาธิต การรวมส่วนต่อประสานกับผู้ใช้ ในแอปพลิเคชัน Java Graphical
แผง WPF พร้อมตรรกะที่สมบูรณ์ซึ่งจะถูกใช้เพื่อสาธิต การรวมส่วนต่อประสานกับผู้ใช้ ในแอปพลิเคชัน Java Graphical
นี่คือตัวอย่างพื้นฐานที่เราเรียกคลาสแบบง่ายที่กำหนดใน CSharpClass.cs จากแอปพลิเคชัน Java ใน CLRCSharpClassCSharpClass.cs เรามีคลาสที่เรียบง่าย
using System ;
namespace MASES . CLRTests
{
public class CSharpClass
{
/// <summary>The method <c>HelloWorld</c> return the "Hello World!!" string</summary>
public String HelloWorld ( )
{
return "Hello World from C#!!" ;
}
/// <summary>The method <c>Add</c> return the sum of two double</summary>
public double Add ( double a , double b )
{
return a + b ;
}
/// <summary>The method <c>Add</c> return the sin of a double</summary>
public double Sin ( double a )
{
return Math . Sin ( a ) ;
}
}
}
ใน /JVM/src/JavaClass.java เรามีแอปพลิเคชัน Java แบบธรรมดา
import java . io . IOException ;
import org . mases . jcobridge .*;
public class CSharpClassUseExample {
public static void main ( String [] args ) {
try {
try {
try {
JCOBridge . Initialize ( "" );
} catch ( JCException e ) {
e . printStackTrace ();
}
} catch ( IOException e ) {
e . printStackTrace ();
}
//declare and create JCOBridge instance
JCOBridge bridge ;
bridge = JCOBridge . CreateNew ();
// adds the path where extarnal assemblies where found
bridge . AddPath ( "../CLR/Output/" );
// add REFERENCES to the .dll file
bridge . AddReference ( "CSharpClass" );
// GENERATE Object
JCObject CSharpObject = ( JCObject ) bridge . NewObject ( "MASES.CLRTests.CSharpClass" );
double a = 2 ;
double b = 3 ;
double c = Math . PI / 2 ;
//Invoke the C# class methods
String hello = ( String ) CSharpObject . Invoke ( "HelloWorld" );
double result = ( double ) CSharpObject . Invoke ( "Add" , a , b );
double sin = ( double ) CSharpObject . Invoke ( "Sin" , c );
System . out . println ( String . format ( "%s %.0f + %.0f = %.0f and sin(%.8f) = %.8f" , hello , a , b , result , c , sin ));
} catch ( JCException jce ) {
jce . printStackTrace ();
System . out . println ( "Exiting" );
return ;
}
}
}
การรันโค้ดเราจะได้ผลลัพธ์ดังนี้:
Hello World from C#!! 2 + 3 = 5 and sin(3,14159265) = 1,00000000
ในตัวอย่างที่ซับซ้อนกว่านี้เล็กน้อยนี้ เราได้รวมการควบคุมที่ซับซ้อนสองแบบที่แตกต่างกันเข้ากับอินเทอร์เฟซผู้ใช้ awt java ซึ่งนำมาจากไลบรารี .NET สองตัว ตัวควบคุมแรกคือ Windows Form ส่วนตัวควบคุมที่สองคือวัตถุ WPF แอปพลิเคชันใน JVMJavasrcAWTWinFormsWPF.java เปิดเผยกระบวนการทั้งหมดตั้งแต่การอ้างอิงการควบคุมและการสร้างไปจนถึงการลงทะเบียนตัวฟังเหตุการณ์ .NET ไปจนถึงการจัดการการเรียกกลับเหตุการณ์ .NET
import java . awt . Frame ;
import java . io . IOException ;
import org . mases . jcobridge .*;
public class AWTWinFormsWPF implements IJCVoidEventEmit {
public static void main ( String args []) {
new AWTWinFormsWPF (). createAndShow ();
}
int cycle = 0 ;
java . awt . TextArea gTextArea ;
// WPF
JCControl gControlWpfControl = null ;
// FORMS
JCControl gControlFormsControl = null ;
void createAndShow () {
try {
// LOGGER
IJCEventLog logger = null ;
try {
try {
JCOBridge . Initialize ( "" );
} catch ( JCException e ) {
e . printStackTrace ();
}
logger = new JCFileEventLog ( "WinFormsWPF.txt" );
} catch ( IOException e ) {
e . printStackTrace ();
}
JCOBridge bridge ;
bridge = JCOBridge . CreateNew ();
bridge . RegisterEventLog ( logger );
// adds the path where extarnal assemblies where found
bridge . AddPath ( "../../CLR/Output/" );
// add REFERENCES
bridge . AddReference ( "WPFTestControl" );
bridge . AddReference ( "WinFormsTestControl" );
// GENERATE CONTROLS
gControlWpfControl = bridge . GetControl ( "MASES.CLRTests.WPFTestControl.TestControl" );
gControlFormsControl = bridge . GetControl ( "MASES.CLRTests.WinFormsTestControl.TestControl" );
// CONFIGURE CONTROLS
gControlWpfControl . RegisterEventListener ( "FromComboBox" , this );
gControlWpfControl . RegisterEventListener ( "FromTextBox" , this );
gControlFormsControl . RegisterEventListener ( "FromComboBox" , this );
gControlFormsControl . RegisterEventListener ( "FromTextBox" , this );
Frame dialog = new Frame ();
gTextArea = new java . awt . TextArea ();
gTextArea . setText ( "This is an AWT TextArea" );
java . awt . GridLayout layout = new java . awt . GridLayout ( 2 , 2 );
dialog . setLayout ( layout );
dialog . add ( gControlWpfControl );
dialog . add ( gControlFormsControl );
dialog . add ( gTextArea );
dialog . validate ();
dialog . setTitle ( "WinForms-WPF AWT integration" );
dialog . setVisible ( true );
dialog . setSize ( 200 , 200 );
} catch ( JCException jce ) {
jce . printStackTrace ();
System . console (). readLine ( "Please press enter" );
System . out . println ( "Exiting" );
return ;
}
}
@ Override
public void EventRaised ( Object ... args ) {
System . out . println ( "EventRaised" );
if ( args [ 1 ] instanceof JCObject ) {
JCObject obj = ( JCObject ) args [ 1 ];
System . out . println ();
try {
if ( obj != null ) {
gTextArea . setText ( "Text area: event: " + obj . toString () + " Content: " + obj . Get ( "Content" ));
}
} catch ( JCException e ) {
e . printStackTrace ();
}
}
}
}
คลาสเดียวที่ให้การดำเนินการแบบ double และ string ที่จะเรียกจาก .NET CLR
คลาสที่มีสองเมธอดและแสดงวิธีการลงทะเบียนและใช้ตัวแปรโกลบอลและอ็อบเจ็กต์ที่ใช้ร่วมกัน
import org . mases . jcobridge .*;
import java . awt .*;
public class GlobalVariableTest
{
public static void createGlobal () throws JCException
{
Dialog dialog = new Dialog (( Dialog ) null );
JCOBridge . RegisterJVMGlobal ( "SharedDialog" , dialog );
}
public static void testMyCLRClass ( Integer a , Integer b ) throws JCException
{
JCObject resultGetCLRObject = ( JCObject ) JCOBridge . GetCLRGlobal ( "MyCLRClass" );
resultGetCLRObject . Invoke ( "Add" , a , b );
}
}
เมธอด createGlobal จะสร้างกล่องโต้ตอบ awt ส่วนกลางและลงทะเบียนเพื่อใช้ได้อย่างราบรื่นจากฝั่ง CLR testMyCLRClass แสดงวิธีใช้อ็อบเจ็กต์โกลบอล CLR ที่ลงทะเบียนแล้ว ในตัวอย่าง CLR เราสร้างอ็อบเจ็กต์นี้จากฝั่ง .NET และเราเรียกฟังก์ชันนี้เพื่อใช้งาน และสาธิตการดำเนินการที่ร้อนแรงซึ่งสะท้อนให้เห็นระหว่าง JVM และ CLR ในลักษณะที่โปร่งใส
คลาส Scala แบบง่ายถูกกำหนดให้ใช้จาก CLR ใน JVMScalascalaclasssrcmainscalaScalaClass.class เรียกคอมไพล์และรันสคริปต์แบตช์ใน JVMScala
ก่อนการเรียกคอมไพล์และรันสคริปต์แบทช์ Scala ไบนารีจะต้องถูกติดตั้ง
import java . lang . _
final class ScalaClass ( aString : String , val anInteger : Int ) {
def this () {
this ( "defaultString" , - 1 )
}
def this ( aBool : Boolean ) {
this ( "defaultString" , - 1 )
}
val scalaString = "This is a Scala String"
def add ( x : Int , y : Int ): Int = x + y
def stringConcat ( args : Array [ String ]): String =
{
return args . mkString ( ", " )
}
}
ใน CLRScalaClassUseExampleProgram.cs เรามีแอปพลิเคชันง่ายๆ ที่ใช้ ScalaClass ที่กำหนดไว้
using CommonTest ;
using MASES . JCOBridge . C2JBridge ;
using MASES . LicenseManager . Common ;
using System ;
using System . IO ;
namespace ScalaClassUseExample
{
class TestClass : BaseTestClass
{
public override string GetProjectClassPath ( )
{
#if ! JCOBRIDGE_CORE
return @"....JVMScalaOutput" ;
#else
return @"......JVMScalaOutput" ;
#endif
}
public override string ClassPath
{
get
{
return new ClassPathBuilder ( GetProjectClassPath ( ) + @"*" , @"C:Program Files (x86)scalalib*.jar" ) . Build ( ) ;
}
}
public override void Execute ( )
{
int a = 10 ;
int b = 15 ;
var scalaClass = DynJVM . ScalaClass . @new ( ) ;
var result = scalaClass . add ( a , b ) ;
Console . WriteLine ( "{0} + {1} = {2}" , a , b , result ) ;
string [ ] strings = new string [ ] { "One" , "Two" , "Three" } ;
var concatString = scalaClass . stringConcat ( strings ) ;
Console . WriteLine ( "{0} = {1}" , string . Concat ( strings ) , concatString ) ;
Console . WriteLine ( "Press Enter to exit" ) ;
Console . ReadLine ( ) ;
}
}
class Program
{
static void Main ( string [ ] args )
{
try
{
new TestClass ( ) . Execute ( ) ;
}
catch ( Exception e )
{
Console . WriteLine ( e . Message ) ;
Console . WriteLine ( "Press any key." ) ;
Console . ReadKey ( ) ;
}
}
}
}
ใน Scala ไลบรารีที่จำเป็นทั้งหมดจะถูกเพิ่มลงในเส้นทางฐานอย่างชัดเจน
ในตัวอย่างนี้ เราเรียกวัตถุ .NET จากภาษา Scala ผ่าน JCOBridge ก่อนการเรียกคอมไพล์และรันสคริปต์แบตช์ Scala ไบนารีจะต้องถูกติดตั้ง
import java . util . Iterator
import org . mases . jcobridge . _
object Main extends App {
try
{
JCOBridge . Initialize ();
}
catch
{
// catch to avoid problem with Trial mode of JCOBridge
case jce : JCException => System . out . println ( jce . getMessage )
}
val bridge = JCOBridge . CreateNew ()
// adds a new reference to WPF
bridge . AddReference ( "PresentationFramework" )
// get MessageBox type
val msgType = bridge . GetType ( "System.Windows.MessageBox" )
// invoke static method to show a message box on the screen
msgType . Invoke ( "Show" , "Please press enter to continue" )
// get .NET type
val enumType = bridge . GetType ( "System.Environment" )
// invokes static method
val genObj = enumType . Invoke ( "GetLogicalDrives" )
// retrieve the iterator
val iteratorObj = genObj . asInstanceOf [ JCObject ]. iterator
// iterate on all object and print the value
while ( iteratorObj . hasNext ) println ( iteratorObj . next )
// invoke static method to show a message box on the screen
msgType . Invoke ( "Show" , "Please press enter" )
// event callback example
val tObj = bridge . NewObject ( "System.Timers.Timer" ); // create the timer object
val timerObj = tObj . asInstanceOf [ JCObject ];
// register an event handler when the Timer elaps
timerObj . RegisterEventListener ( "Elapsed" , new ScalaJCVoidEventEmit ());
// set Interval property
timerObj . Set ( "Interval" , 1000 ); // set properties
// enable the Timer
timerObj . Set ( "Enabled" , true ); // start timer
// invoke static method to show a message box on the screen
msgType . Invoke ( "Show" , "Please press enter" )
}
final class ScalaJCVoidEventEmit () extends JCVoidEventEmit {
override def EventRaised ( args : Object *) : Unit =
{
// scala seems to have a problem to translate var args argument into JVM bytecode. This method is needed to avoid compilation problems
}
// this method defines exactly the signature expected from the event
def EventRaised ( sender : Object , arg : Object ) : Unit =
{
println ( "Timer Elapsed" )
}
}