从java通信到C ++程序

我想从java中执行外部.exe程序。 .exe是一个CLI应用程序,它在运行时接收输入(scanf())并根据输入输出。 我可以调用程序从java执行

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

我知道有很多关于这个话题的问题。 但我发现它们中的任何一个都没用。

我使用的function相当难看。 这会将命令传递给Runtime.getRuntime().exec ,然后将结果保存到String中,并在结尾处返回String。 您可以选择是否只需要最后一行(或所有输出)以及是否要从进程中保存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; } 

您可以使用JNI作为@ linuxuser27建议,或者您可以使用SWIG ,这有助于使从Java – > C ++进行通信的过程不那么痛苦。

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

协议缓冲区是Google的语言中立,平台中立,可扩展的机制,用于序列化结构化数据 – 思考XML,但更小,更快,更简单。 您可以定义数据的结构化时间,然后使用特殊生成的源代码,可以使用各种语言(Java,C ++或Python)轻松地在各种数据流中编写和读取结构化数据。

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

更新:

JNI是Java与JRE运行的底层本机环境交互的一种方式。 此方法需要您创建在Java程序启动时加载到JRE中的DLL 。 然后,此JNI DLL将包含一个方法,该方法可以在Java程序中调用,该方法将数据传递到JNI DLL,然后可以通过命名管道或共享内存与C ++项目进行通信。

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

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

有几件事:

  • 首先,如果你还没有这样做,请阅读这篇至关重要的文章: 当Runtime.exec不会
  • 接下来,Java可以通过多种方式与其他应用程序进行通信,最简单的方法是通过标准输入和输出流。 你尝试过使用这些吗?
  • 接下来是JNI和更简单的JNA,但是你说你的C ++程序是通过CLI运行的,这表明你有一个.NET dll,而不是真正的Windows dll。 这样吗? 如果是这样,它将使Java和C ++之间的通信更加困难。
  1. 您可以直接执行.exe程序。 您只需要提供完整路径。 相对路径也可以。

  2. 您可以使用管道与外部进程连接: 将命令发送到命令 , 从命令读取输出

解决方案可以在这里找到问题获取输出并将输入传递给在java下运行的执行进程