Общение с программой на C ++ из Java - PullRequest
4 голосов
/ 07 мая 2011

Я хочу выполнить внешнюю программу .exe изнутри Java. .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. Есть несколько вещей, на которые стоит обратить внимание: =

1) Связь с .exe должна выполняться во время выполнения (не через main (args)) 2) Java-программа должна взять выходные данные и сохранить их в некоторой переменной / панели для использования в будущем 3) Программа для выполнения может отличаться (например, пользователь может выбрать .exe, который вообще не принимает никаких данных) ........ Так что в основном графический интерфейс Java будет действовать как 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 ]

3 голосов
/ 07 мая 2011

Довольно уродливая маленькая функция, которую я использую. Это принимает команду, которая будет передана в 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;
    }
1 голос
/ 07 мая 2011

Буферы протокола Google было бы хорошим вариантом для взаимодействия Java / C ++.

Буферы протокола - это независимый от языка, не зависящий от платформы, расширяемый механизм Google для сериализации структурированных данных.- думать XML, но меньше, быстрее и проще.Вы определяете, как вы хотите, чтобы ваши данные были структурированы один раз, затем вы можете использовать специальный сгенерированный исходный код, чтобы легко записывать и считывать ваши структурированные данные в различные потоки данных и из них, используя различные языки - Java, C ++ или Python.

1 голос
/ 07 мая 2011

Вы можете использовать JNI, как предлагает @ linuxuser27, или вы можете использовать SWIG , который помогает сделать процесс общения с Java -> C ++ немного менее болезненным.

1 голос
/ 07 мая 2011

Я бы посмотрел на JNI и использовал бы некоторый тип IPC для связи с проектом C ++.

Обновление:

JNI - это способ Java взаимодействовать с базовой собственной средой, в которой работает JRE. Этот метод потребует от вас создания DLL, которая загружается в JRE при запуске вашей Java-программы. Эта JNI DLL будет содержать метод, который может быть вызван из вашей Java-программы и который будет передавать данные в JNI DLL, которая затем может обмениваться данными с проектом C ++ через именованный канал или общую память.

Именованный канал будет создан с использованием CreateNamedPipe Win32 API. В JNI DLL вы, скорее всего, создадите сервер , а в проекте C ++ вы создадите клиент . Обратите внимание, что пример сервера является многопоточным, но для простоты может быть легко преобразован в модель с одним потоком.

Обратите внимание, что это не простая задача. Другие ответы предлагают несколько более простых подходов: JNA и передачу данных в проект C ++ через stdin.

0 голосов
/ 07 мая 2011
  1. Вы можете запускать программы .exe напрямую. Вам просто нужно указать полный путь. Относительный путь также будет в порядке.

  2. Можно использовать каналы для взаимодействия с внешним процессом: Отправка ввода в команду , Чтение вывода из команды

0 голосов
/ 07 мая 2011

Пара вещей:

  • Прежде всего, если вы этого не сделали, прочитайте эту критически важную статью: Когда Runtime.exec не будет
  • Далее, есть несколько способов взаимодействия Java с другими приложениями, и, вероятно, самый простой - через стандартные потоки ввода и вывода. Вы пробовали использовать их?
  • Далее идет JNI и более простая JNA, но вы заявили, что ваша программа на C ++ работает через CLI, что подсказывает мне, что у вас есть .NET dll, а не настоящая Windows dll. Это так? Если это так, то это затруднит взаимодействие между Java и C ++.
...