[英]Communicating to a C++ program from java
我想从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);
}
}
我知道有很多关于这个话题的问题。 但我发现它们中的任何一个都没用。
我使用的功能相当丑陋。 这会将命令传递给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并使用某种类型的IPC与C ++项目进行通信。
更新:
JNI是Java与JRE运行的底层本机环境交互的一种方式。 此方法需要您创建在Java程序启动时加载到JRE中的DLL 。 然后,此JNI DLL将包含一个方法,该方法可以在Java程序中调用,该方法将数据传递到JNI DLL,然后可以通过命名管道或共享内存与C ++项目进行通信。
命名管道将使用CreateNamedPipe Win32 API创建。 在JNI DLL中,您很可能会创建一个服务器,而在C ++项目中,您将创建客户端 。 请注意,服务器示例是多线程的,但为了简单起见,可以轻松地将其转换为单个线程模型。
请注意,这不是一项简单的任务。 其他答案提供了一些更容易的方法, JNA并通过stdin将数据传递给C ++项目。
您可以使用JNI作为@ linuxuser27建议,或者您可以使用SWIG ,这有助于使从Java - > C ++进行通信的过程不那么痛苦。
Google Protocol Buffers是Java / C ++互操作性的一个很好的选择。
协议缓冲区是Google的语言中立,平台中立,可扩展的机制,用于序列化结构化数据 - 想想XML,但更小,更快,更简单。 您可以定义数据的结构化时间,然后可以使用特殊生成的源代码轻松地在各种数据流中使用各种语言(Java,C ++或Python)编写和读取结构化数据。
有几件事:
解决方案可以在这里找到问题获取输出并将输入传递给在java下运行的执行进程
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.