3

我已经开始使用 IKVM 将 Java 库转换为 .NET CIL。我可以成功编写一个 C# 程序,该程序引入(inproc)翻译的 Java 程序集作为参考,并调用翻译的 Java 代码。

我的问题是,是否有人熟悉如何使用 IKVM 从 Java 调用(回调)到 C#?我一直在寻找一个好的教程或解释,但还没有看到。

任何帮助表示赞赏。谢谢,

4

2 回答 2

5

女士们,先生们,我想出了自己的问题。先上代码,后跟步骤。

Java 类

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# 类

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) 编写你的 Java 应用程序

2) 将您的 *.class 文件转换为 jar 文件 (jar -cf myjar.jar *.class)

3)将jar文件转换为.NET程序集(ikvmc -reference:csharpassembly.dll myjar.jar)

此时应该工作。您可以运行您的 C# 程序,让它调用转换后的 Java 程序,反之亦然。注意 ikvmc 调用中的“-reference”标志。这会告诉 IKVM 在转换 Java 代码时 csharpassembly.dll 有一些需要注意的类定义。

于 2010-11-10T17:46:07.973 回答
0

JaapM,我认为 mj_ 解决方案中的 CSharpLibrary 是来自第三个 C# DLL 项目 (cshardassembly.dll) 的临时类,他首先编译然后在实际的 java 和 C# 代码之间共享。里面有什么并不重要,这个想法是双方都有一段预先知道的代码(类)。这是矫枉过正,如果我是正确的。

我知道,这已经过去了很长时间,但我想在这里发布一个适合我的简短解决方案,因为我在它上面浪费了太多时间,而且 IKVM 文档很差:

爪哇:

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 + "]");
    }
}

不要忘记将 mscorlib.dll 转换为 jar 并将其附加到您的 java 项目以支持 cli 导入。构建它并使用 -target:library 参数在 jar 上运行 ikvmc.exe,并将生成的 DLL 添加到 C# 项目中。

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));
    }
}

输出:

DelegateTarget 已执行:[你好,世界]!
回调返回 [42]

于 2016-02-12T03:57:41.427 回答