Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Как я могу перенаправить вывод консоли JNI в представление консоли Eclipse, когда подключаемый модуль Eclipse использует JNI?

Автор вопроса: mahonyaОтветов: 3

У меня есть плагин Eclipse (A), который зависит от другого плагина (B). Плагин B - это просто оболочка вокруг jar, которая содержит собственную dll и выполняет функции jni. Учитывая эту настройку, у меня есть следующий код в методе запуска класса Activator A:

MessageConsole jniConsole = new MessageConsole("Opereffa Output", null);
ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[] { jniConsole });
ConsolePlugin.getDefault().getConsoleManager().showConsoleView(jniConsole);
MessageConsoleStream stream = jniConsole.newMessageStream();
System.setOut(new PrintStream(stream));
System.setErr(new PrintStream(stream));

Когда подключаемый модуль A выполняет свои функции, любое использование System.out фактически переходит на консоль в Eclipse. Но собственный код, используемый JNI, также записывает в выходной поток, который я не могу получить. Во время разработки выходные данные JNI поступают на консоль экземпляра Eclipse, который запустил работающий экземпляр, содержащий подключаемые модули.

Итак, как мне получить вывод JNI и отобразить его в консоли?

  • Какие функции регистрируют сообщения в нативном коде? printf, fprintf, puts?... Не могли бы вы переписать код, изменив функцию регистрации? Jean-Philippe Pellet 13.12.2010
  • Поскольку задействован JNI: насколько переносимым должно быть решение? На каких платформах он должен работать хотя бы? A.H. 09.10.2011

pluginseclipseredirectconsolejava-native-interface

Ответы

Ответ 1 · рейтинг 1 · Mike Houston

Вы можете попробовать использовать freopen для перенаправления stdout точно так же, как и вы. на Java, но на нативной стороне. Вопрос в том, будет ли это работать, если вы использовали его в своем собственном плагине (с новой dll JNI): его может потребоваться использовать из dll, выполняющего вывод консоли, я понятия не имею о взаимодействии между потоками между DLL . Если stdout ссылается на общий поток для всего процесса, возможно, это сработает.

Ответ 2 · Aaron Digulla

Вы не можете, правда. Собственная DLL использует методы stdio, к которым вы не можете получить доступ из Java. Если вы пишете в System.out, среда выполнения Java в конечном итоге использует те же методы, но по очевидным причинам изменения в System.out не влияют на базовую среду выполнения C.

Есть аппаратное решение: приобретите второй монитор, чтобы постоянно видеть терминал, в котором запускали Eclipse.

Ответ 3 · Sam Ginrich

Например. Eclipse 2019-06 регулярно делегирует std::printf(...) и std::cout из кода JNI в консольное представление.

Промывка (=фактически напечатанная) выполняется fflush(stdout);.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы