问题
I've started using IKVM to translate Java libs into .NET CIL. I can successfully write a C# program that pulls in (inproc) a translated Java assembly as a reference and make calls to the translated Java code.
My question is, is anyone familiar w/ how to make calls (callbacks) from Java to C# using IKVM? I've been looking for a good tutorial or explanation but haven't seen one yet.
Any help is appreciated. Thanks,
mj
回答1:
Ladies and Gentlemen, I figured out my own question. Code first followed by steps.
Java Class
public class TestClass {
private cli.CSharpLibrary.Library m_lib = null;
public void AddDelegate( cli.CSharpLibrary.Library lib )
{
m_lib = lib;
}
public void FireDelegate()
{
if( m_lib != null )
{
m_lib.ExecuteRunnableDelegate();
}
}
public void PrintInt()
{
System.out.print(23);
}
}
C# Class
using ikvm.runtime;
using CSharpLibrary;
namespace CSharp
{
class Program
{
public static void DelegateTarget()
{
Console.WriteLine("DelegateTarget Executed!");
}
static void Main(string[] args)
{
Library lib = new Library();
lib.m_runnableDelegate = new Delegates.RunnableDelegate(DelegateTarget);
TestClass tc = new TestClass();
tc.AddDelegate(lib);
tc.FireDelegate();
}
}
}
1) Write your Java app
2) Convert your *.class files into a jar file (jar -cf myjar.jar *.class)
3) Convert the jar file into a .NET assembly (ikvmc -reference:csharpassembly.dll myjar.jar)
Should work at this point. You can run your C# program, have it call the converted Java program and vice versa. Watch out for the "-reference" flag on the ikvmc call. This tells IKVM when it's converting the Java code that csharpassembly.dll has some class definitions that it needs to watch out for.
回答2:
JaapM, I think CSharpLibrary in mj_'s solution is a transient class from third C# DLL project (cshardassembly.dll), that he compiles first and then shares between actual java and C# code. It doesn't matter what's in it, the idea is that both sides have a piece of code (class) known in advance. This is overkill, if I'm correct.
I know, it's a long time passed but I would like to post a short solution here that works for me, cuz I wasted too much time on it and IKVM documentation is very poor:
Java:
package what.ever.package;
import cli.System.Delegate;
import cli.System.Int32;
public class SomeJavaClass
{
public static void setCallback(Delegate callback)
{
// I call delegate in static setter to keep example short,
// but you may save it and call later...
Int32 result = (Int32)callback.DynamicInvoke("hello", "world");
System.out.println("Callback returned [" + result + "]");
}
}
Don't forget to convert mscorlib.dll into jar and attach it to your java project to support cli imports. build it and run ikvmc.exe on jar with -target:library parameter and add resulting DLL into C# project.
C#:
using what.ever.package
class Program
{
// signature of delegate must match target function.
public delegate Int32 TheDelegateItself(String a, String b);
// callback that we pass into java.
public static Int32 DelegateTarget(String a, String b)
{
Console.WriteLine("DelegateTarget Executed: [" + a + ", " + b + "]!");
return 42;
}
static void Main(string[] args)
{
// again, static call to keep it short
// but you may want a class instance in most cases.
SomeJavaClass.setCallback(new TheDelegateItself(DelegateTarget));
}
}
output:
DelegateTarget Executed: [hello, world]!
Callback returned [42]
来源:https://stackoverflow.com/questions/4145208/ikvm-c-sharp-to-java-interop-with-callback-using-ikvm