与 C++ 进行通信来自java的程序

发布于 2024-11-05 20:04:18 字数 993 浏览 1 评论 0原文

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

       }

我知道有很多关于这个主题的问题。但我找不到它们中的任何一个很有用。

I want to execute a external .exe program from within java. The .exe is a CLI application which takes input in runtime( scanf() ) and outputs depending on the input. I can call the program to execute from java using

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

instead of

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

But I think it is also possible to call a program from within java. I have my whole program written in C++ just need a GUI which is written in java. There are a few things to notice:=

1) The communication with the .exe should be runtime (not through main(args) )
2) The java program should take the outputs and store in some variable / panel to use for future
3) Program to be executed can differ ( for example user may select a .exe that doesnt take any input at all)
........So basically the java GUI will act as a 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);
            }

       }

I know there are a lot of questions about this topic out there. But i cant find any of them much useful.

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

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

发布评论

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

评论(7

陪你搞怪i 2024-11-12 20:04:18

我使用的相当丑陋的小功能。它接收要传递给 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;
    }

Rather ugly little function that I use. This takes in the command to be passed to Runtime.getRuntime().exec, then saves the results into a String, and returns the String at the end. You can pick whether you only want the last line (or all output) and whether you want to save the stdout or stderr string from the process.

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;
    }
写给空气的情书 2024-11-12 20:04:18

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

You could use JNI as @linuxuser27 suggests, or you could use SWIG which helps to make the process of communicating from Java --> C++ a little less painful.

烟沫凡尘 2024-11-12 20:04:18

Google Protocol Buffers 是实现 Java/C++ 互操作性的不错选择。

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

Google Protocol Buffers would be a good option for Java/C++ interoperability.

Protocol buffers are Google's
language-neutral, platform-neutral,
extensible mechanism for serializing
structured data – think XML, but
smaller, faster, and simpler. You
define how you want your data to be
structured once, then you can use
special generated source code to
easily write and read your structured
data to and from a variety of data
streams and using a variety of
languages – Java, C++, or Python.

素年丶 2024-11-12 20:04:18

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

更新

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

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

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

I would look at JNI and use some type of IPC to communicate with the C++ project.

Update:

JNI is a way for Java to interface with the underlying native environment the JRE is running on. This method would require you to create a DLL that is loaded into the JRE when your Java program starts. This JNI DLL would then contain a method which could be called from within your Java program that would pass data into the JNI DLL that could then communicate to the C++ project via a named pipe or shared memory.

The named piped would be create using the CreateNamedPipe Win32 API. Within the JNI DLL you would most likely create a server and in the C++ project you would create the client. Note that the server example is multi-threaded but can easily be converted to a single thread model for simplicity.

Note that this is not a simple task. The other answers offer some approaches that are easier, JNA and passing data to the C++ project via stdin.

柳絮泡泡 2024-11-12 20:04:18

有几点:

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

A couple of things:

  • First and foremost, if you haven't done so, read this critically important article: When Runtime.exec won't
  • Next, there are several ways for Java to communicate to other applications, and probably the easiest is via standard input and output streams. Have you tried using these?
  • Next there's JNI and the easier JNA, but you stated that your C++ program is running via CLI which suggests to me that you have a .NET dll, not a true Windows dll. Is this so? If so, it would make communication between Java and C++ more difficult.
离鸿 2024-11-12 20:04:18
  1. 您可以直接执行.exe程序。您只需要提供完整路径。相对路径也可以。

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

  1. You can execute .exe programs directly. You just need to supply the full path. Relative path will also be ok.

  2. You can use pipes to interface with an external process: Sending Input to a Command, Reading Output from a Command

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