2011-05-07 97 views
4

我想在java中执行一个外部.exe程序。 .exe是一个CLI应用程序,它根据输入在运行时输入(scanf())和输出。我可以调用程序从Java执行使用从Java通信到C++程序

Process p = Runtime.getRuntime().exec("cmd /c start a.exe"); 

代替

Process p = Runtime.getRuntime().exec("cmd /c start a.exe"); 

但我认为这也可以从Java中调用的程序。我用C++编写我的整个程序只需要一个用java编写的GUI。有几件事要注意:=

1)与.exe的通信应该是运行时(不通过main(args)) 2)java程序应该获取输出并存储在某个变量/面板中用于未来 3)要执行的程序可能会有所不同(例如,用户可能会选择一个完全不接收任何输入的.exe) ........所以基本上,Java GUI将充当RuntimeEnv

public void runEXE() 

     { 
      String s = null; 

      try { 
       Process p = Runtime.getRuntime().exec("cmd /c a.exe"); 
       System.exit(0); 
      } 
      catch (IOException e) { 
       System.out.println("exception happened - here's what I know: "); 
       e.printStackTrace(); 
       System.exit(-1); 
      } 

     } 

我知道这里有很多关于这个话题的问题。但我找不到任何有用的东西。

回答

1

我想看看JNI并使用某种类型的IPC与C++项目进行通信。

更新:

JNI是Java与JRE正在运行的底层本地环境相连接的方法。当你的Java程序启动时,这种方法需要你去create a DLL that is loaded into the JRE。然后,这个JNI DLL将包含一个可以从Java程序中调用的方法,该方法将数据传递给JNI DLL,然后该JNI DLL可以通过命名管道或共享内存与C++项目通信。

命名管道将使用CreateNamedPipe Win32 API创建。在JNI DLL中,您很可能会创建server,而在C++项目中,您将创建client。请注意,服务器示例是多线程的,但为了简单起见,可以轻松地将其转换为单个线程模型。

请注意,这不是一个简单的任务。其他答案提供了一些更简单的方法,JNA并通过stdin将数据传递给C++项目。

+0

我如何做到这一点发现? – shababhsiddique 2011-05-07 18:13:23

+0

你在使用什么操作系统? – linuxuser27 2011-05-07 18:15:38

+0

的Windows 7 ....... – shababhsiddique 2011-05-07 18:23:25

1

您可以像@ linuxuser27建议的那样使用JNI,或者您可以使用SWIG,这有助于使Java - > C++的通信过程不那么痛苦。

1

Google Protocol Buffers将是Java/C++互操作性的一个很好的选择。

协议缓冲区是谷歌的 语言中立,平台中立, 扩展机制序列化 结构化数据 - XML,但是 更小,更快,更简单。你 定义你希望你的数据被 结构一次,然后就可以使用 特殊生成的源代码,以 轻松地将结构化 数据写入和读取,并从各种数据 流和使用各种 语言 - Java,C++或Python。

0

几件事情:

  • 首先,如果您还没有这样做,阅读非常重要文章:When Runtime.exec won't
  • 下,有几种方法对Java进行通信其他应用程序,可能最简单的是通过标准输入和输出流。你有没有尝试过使用这些?
  • 下一页有JNI和JNA更容易,但你说,你的C++程序通过CLI这表明,我认为你有一个.NET的DLL,而不是一个真正的Windows DLL运行。这是吗?如果是这样,它会使Java和C++之间的通信更加困难。
+0

我似乎没有找到一个同时进行输入输出 – shababhsiddique 2011-05-07 18:36:40

+0

@shababhsiddique:您将需要使用单独的线程这一点。我上面链接到的文章的最后一页显示了一个简单的例子。 – 2011-05-07 18:54:01

+0

我之前没有使用线程..我可以开始吗? – shababhsiddique 2011-05-08 04:09:03

0
  1. 您可以直接执行.exe程序。你只需要提供完整的路径。相对路径也可以。

  2. 您可以使用管道与外部程序接口:Sending Input to a CommandReading Output from a Command

+0

他们没有的做输入输出同时 – shababhsiddique 2011-05-07 18:36:21

+0

您可以在一个程序中合并两个例子。请注意,您需要在单独的线程中执行输入,因为它使用阻止读取()。 – 2011-05-07 19:02:50

+0

这是我的问题在这里..怎么 – shababhsiddique 2011-05-08 04:08:33

3

,我用比较难看的小功能。这需要将命令传递给Runtime.getRuntime().exec,然后将结果保存到字符串中,并在最后返回字符串。您可以选择是否只需要最后一行(或所有输出)以及是否要保存过程中的stdout或stderr字符串。

private static String systemResult(String cmd, boolean append, boolean useErr) 
    { 
    String result = ""; 
    try{ 
     // spawn the external process 
     //printCmd(cmd); 
     Process proc = Runtime.getRuntime().exec(cmd); 
     LineNumberReader lnr1 = new LineNumberReader(new InputStreamReader(proc.getErrorStream())); 
     LineNumberReader lnr2 = new LineNumberReader(new InputStreamReader(proc.getInputStream())); 
     String line; 
     int done = 0; 
     while(lnr1 != null || lnr2 != null){ 
     try{ 
      if(lnr1.ready()){ 
      if((line = lnr1.readLine()) != null){ 
       //System.err.println("A:" +line); 
       if(useErr){ 
       if(append) result = result + line + "\n"; 
       else result = line; 
       } 
      } 
      }else if(done == 1){ 
      done = 2; 
      } 
     }catch(Exception e1){ 
      try{ lnr1.close(); }catch(Exception e2){} 
      lnr1 = null; 
     } 

     try{ 
      if(lnr2.ready()){ 
      if((line = lnr2.readLine()) != null){ 
       //System.err.println("====>Result: " + line); 
       if(!useErr){ 
       if(append) result = result + line + "\n"; 
       else result = line; 
       } 
      } 
      }else if(done == 2){ 
      break; 
      } 
     }catch(Exception e1){ 
      try{ lnr2.close(); }catch(Exception e2){} 
      lnr2 = null; 
     } 

     try{ 
      proc.exitValue(); 
      done = 1; 
     }catch(IllegalThreadStateException itsa){} 
     } 
     if(lnr1 != null) lnr1.close(); 
     if(lnr2 != null) lnr2.close(); 

     try{ 
     proc.waitFor(); 
     }catch(Exception ioe){ 
     }finally{ 
     try{ 
      proc.getErrorStream().close(); 
      proc.getInputStream().close(); 
      proc.getOutputStream().close(); 
     }catch(Exception e){} 
     proc = null; 
     } 
    }catch(Exception ioe){ 
    } 
    return result; 
    }