2011-05-07 24 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; 
    }