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

У меня есть плагин 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 и отобразить его в консоли?


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


Ответы (3)


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

person Mike Houston    schedule 25.08.2011

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

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

person Aaron Digulla    schedule 31.05.2011

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

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

person Sam Ginrich    schedule 05.05.2021