从java通信到C ++程序

时间:2011-05-07 18:06:47

标签: java windows-7 process runtime

我想从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);
    }

}

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

7 个答案:

答案 0 :(得分:3)

我使用的相当难看的小功能。这会将命令传递给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;
    }

答案 1 :(得分:1)

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

<强>更新

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

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

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

答案 2 :(得分:1)

您可以使用JNI作为@ linuxuser27建议,或者您可以使用SWIG来帮助实现从Java进行通信的过程 - &gt; C ++不那么痛苦。

答案 3 :(得分:1)

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

  

协议缓冲区是Google的   语言中立,平台中立,   用于序列化的可扩展机制   结构化数据 - 想想XML,但是   更小,更快,更简单。您   定义您希望数据的方式   结构化一次,然后你可以使用   特殊生成的源代码   轻松编写和阅读您的结构化   来往各种数据的数据   流和使用各种各样的   语言 - Java,C ++或Python。

答案 4 :(得分:0)

有几件事:

  • 首先,如果您还没有这样做,请阅读这篇极为重要的文章:When Runtime.exec won't
  • 接下来,Java可以通过多种方式与其他应用程序进行通信,最简单的方法是通过标准输入和输出流。你尝试过使用这些吗?
  • 接下来是JNI和更简单的JNA,但你说你的C ++程序是通过CLI运行的,这表明你有一个.NET dll,而不是真正的Windows dll。是这样吗?如果是这样,它将使Java和C ++之间的通信更加困难。

答案 5 :(得分:0)

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

  2. 您可以使用管道与外部流程进行交互:Sending Input to a CommandReading Output from a Command

答案 6 :(得分:0)