Sinapse 플랫폼에서 사용할 수 있는 현장에서 입증된 DLR 플러그인을 기반으로 구축된 JCOBridge는 JVM 및 CLR 세계 통합에서 최고의 성능을 보장합니다.
- CLR 유형 검색
- CLR 개체 인스턴스화
- 정적 메서드 호출
- 인스턴스 메소드 호출
- 정적 속성 가져오기/설정
- 인스턴스 속성 가져오기/설정
- 대리인 설정
- 구독/구독 취소 이벤트
- WPF 컨트롤을 AWT/Swing 창에 통합합니다.
- WinForms 컨트롤을 AWT/Swing 창에 통합
- 복잡한 .NET 그래픽 사용자 인터페이스 개체를 AWT/Swing 창에 통합
- 사용자 인터페이스 컨트롤, 속성 및 이벤트 관리
- JVM 클래스 검색
- JVM 객체 인스턴스화
- 정적 메서드 호출
- 인스턴스 메소드 호출
- 정적 필드 가져오기/설정
- 인스턴스 필드 가져오기/설정
- 동적 액세스를 사용하여 Java 언어에서와 마찬가지로 원활한 방식으로 코드를 작성합니다.
- 특정 인터페이스를 사용하여 메소드 및 필드를 직접 관리합니다.
JCOBridge(JVM-CLR 개체 브리지)를 사용하면 CLR/.NET 언어에서 java 및 scala와 같은 JVM 기본 언어를 실행할 수 있으며 그 반대의 경우도 가능합니다. 라이브러리, 구성 요소를 가져오고 사용할 수 있으며 하나의 언어에서 그래픽 사용자 인터페이스를 관리할 수도 있습니다. 프로그래밍 세계를 다른 세계로. 자세한 내용은 www.jcobridge.com에서 확인하세요.
예제를 탐색하려면 다음 단계를 수행해야 합니다.
이 저장소에서는 JCObridge가 지원하는 다양한 프로그래밍 언어에 대한 예제 코드를 찾을 수 있습니다. 예제는 관련 프로젝트가 포함된 두 개의 기본 폴더인 JVM과 CLR로 구성됩니다. 실행하기 전에 코드를 실행하기 전에 두 세계의 예제를 컴파일해야 합니다. 왜냐하면 외부 코드의 런타임 컴파일은 수행되지 않고 실행만 수행되기 때문입니다.
크로스 플랫폼 GUI 프로젝트는 AWT를 사용하여 Windows 및 Linux 호스트에서 .NET Core용 크로스 플랫폼 그래픽 사용자 인터페이스를 만드는 방법을 보여줍니다. Swing을 사용하려면 코드 내의 컨트롤을 원하는 컨트롤로 변경하기만 하면 됩니다.
이는 .NET 애플리케이션에서 JavaClass.java에 정의된 단순 클래스를 호출하는 기본 예입니다. /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
이 예제는 .NET TestClass 클래스에서 환경 매개변수가 구성되는 Java 클래스 사용 예제 의 확장입니다.
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의 기능을 탐색하는 보다 복잡한 애플리케이션입니다. - 동적 JVM 래퍼를 사용하여 .NET 환경에서 Java 코드 실행 - 공유 객체 관리 - Java Virtual Machine 측에 CLR 객체 등록 - 등록된 객체 사용 JVM 측에서 - JVM 등록 클래스의 메소드를 호출하고 작업이 CLR 객체에 반영되도록 합니다. - JVM 측에서 대화 상자를 생성하고 .NET 코드에서 사용합니다.
이 라이브러리에는 JVM에서 호출할 이중 및 문자열 작업을 제공하는 단일 클래스가 포함되어 있습니다.
Java 그래픽 애플리케이션에서 사용자 인터페이스 통합을 시연하는 데 사용되는 완전한 논리가 포함된 Windows Form 패널입니다.
Java 그래픽 애플리케이션에서 사용자 인터페이스 통합을 시연하는 데 사용되는 완전한 논리가 포함된 WPF 패널입니다.
이는 Java 애플리케이션에서 CSharpClass.cs에 정의된 단순 클래스를 호출하는 기본 예입니다. 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
이 좀 더 복잡한 예에서는 두 개의 .NET 라이브러리에서 가져온 두 개의 서로 다른 복잡한 컨트롤을 awt Java 사용자 인터페이스에 통합합니다. 첫 번째 컨트롤은 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 ();
}
}
}
}
.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 클래스는 JVMScalascalaclasssrcmainscalaScalaClass.class의 CLR에서 사용되도록 정의됩니다. 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에서는 필요한 모든 라이브러리가 기본 경로에 명시적으로 추가됩니다.
이 예에서는 JCOBridge를 통해 Scala 언어에서 .NET 개체를 호출합니다. 호출 컴파일 및 배치 스크립트 실행 전에 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" )
}
}