【问题标题】:JNI4NET - how to run Java application from C# Class Library project?JNI4NET - 如何从 C# 类库项目运行 Java 应用程序?
【发布时间】:2014-01-09 03:00:55
【问题描述】:

我有 Java swing 应用程序,我想从 C# 运行它。

当我从 WindowsFormsApplication 使用它时它可以正常工作(请参阅下面的工作版本)。我将 WindowsFormsApplication 窗口设置为不可见,并且在我用 Java 调用 System.exit(0); 后应用程序退出。但是当我尝试使用 ClassLibrary 项目运行相同的项目时,我无法调用Application.Run();,因此程序立即退出。 (在使用断点的调试模式下,我可以看到带有 GUI 的 Java 程序正确初始化并开始运行)。如何让它等到Java程序退出?

使用 WindowsFormsApplication 的工作示例:

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

using java.io;
using java.lang;
using java.util;
using net.sf.jni4net;
using net.sf.jni4net.adaptors;

using tt_factory;

namespace BookMap
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string [] args)
        {
            Init();
            TT_Factory.create_replay(); // creates Java GUI
            Application.Run();
        }

        private static void Init()
        {
            BridgeSetup bridgeSetup = new BridgeSetup(true);
            bridgeSetup.AddJVMOption("-Xms900m");
            bridgeSetup.AddAllJarsClassPath(Application.StartupPath + "\\..\\lib");
            bridgeSetup.JavaHome = Application.StartupPath + "\\..\\jre";
            Bridge.CreateJVM(bridgeSetup);
            Bridge.RegisterAssembly(typeof(TT_Factory).Assembly);
        }
    }
}

使用 ClassLibrary 项目和 ConsoleApplication 作为测试的示例

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            BookMap.create_replay();
            /***** This method is implemented by ClassLibrary project:
             public static void create_replay() 
             {
                init_jvm();
                TT_Factory.create_replay();
             }
             ***** How to make program to wait here ? *****/
        }
    }
}

更新:

我尝试启动新线程,但结果相同:程序立即退出。

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread thread = new Thread(new ThreadStart(BookMap.create_replay));
            thread.Start();
            thread.Join();
        }
    }
}

【问题讨论】:

  • 您能解释一下为什么要从不能保证在用户上下文中运行的东西中调用交互式程序吗?
  • 我有一个完整的 GUI 应用程序,用 Java swing 编写。现在我想让它可以从 C# 访问,因为应用程序所需的一些数据源只有 C# API。但它已经在 WindowsFormsApplication 中运行良好。我只是无法使用 ClassLibrary 项目使其运行。
  • 为了清楚起见,让我们重新表述我的问题:您有一个期望在基于用户的上下文中运行的应用程序(有人登录到机器上并且将查看您希望显示的漂亮 UI)-您想从一段不知道向客户端显示 UI 的代码开始说 UI --- 你为什么认为这是一件好事?是的,这是可能的(实际上相当简单),但很少,如果有的话,是有意义的。您尚未描述您希望所述应用程序运行的环境,因此很难猜测它为什么会发生 - 只知道这是一个坏主意。
  • 我只想让 C# 程序(ClassLibrary 或 ConsoleApplication)一直运行到 Java 工作为止。就像使用 WindowsFormsApplication 一样。我很乐意解释 Java 应用程序是什么以及为什么我需要能够使用 C# 来运行它,但我认为这可能是题外话,甚至被视为宣传。
  • @Serg 您的 .Net 应用程序应该创建一个对象,以便在 Java UI 完成时收到通知,并执行 WaitOne。当 Java 代码完成后,对本地 Windows DLL 进行 JNI 调用,由您的 .Net 应用程序加载,这反过来将触发先前创建的对象上的 Notify。 .Net 应用程序随后将唤醒并终止。

标签: c# java-native-interface jni4net


【解决方案1】:

这是一个有效的简单解决方案。我还不明白怎么做,但是程序一直等到 Java 应用程序调用 System.exit(0),然后不管 Console.Read() 退出;

来自MSDN当您键入输入字符时,Read 方法会阻止其返回;当你按下 Enter 键时它会终止。

在这种情况下,没有人在控制台中按 Enter。

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            BookMap.create_replay();
            Console.Read();
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-20
    • 2012-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-06
    相关资源
    最近更新 更多