使用 IKVM 进行回调的 IKVM C#​​ 到 Java 互操作

发布于 2024-10-02 10:07:31 字数 207 浏览 3 评论 0原文

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

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

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

米杰

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

回忆那么伤 2024-10-09 10:07:31

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

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:csharp assembly .dll myjar.jar)

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

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.

逆光下的微笑 2024-10-09 10:07:31

JaapM,我认为 mj_ 解决方案中的 CSharpLibrary 是来自第三个 C# DLL 项目 (cshard assembly.dll) 的瞬态类,他首先编译该类,然后在实际的 java 和 C# 代码之间共享。其中包含什么并不重要,其思想是双方都有一段预先已知的代码(类)。如果我是对的话,这太过分了。

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

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

不要忘记将 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 执行:[hello, world]!
返回回调[42]

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]

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文