当Eclipse插件使用JNI时,我该如何将JNI控制台输出重定向到Eclipse控制台视图?

24

我有一个Eclipse插件(A),它依赖于另一个插件(B)。插件B只是一个包装了一个包含本地dll和执行jni功能的jar的包装器。

在这种设置下,我在A的Activator类的start方法中有以下代码:

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的输出并显示在控制台中呢?


2
哪个函数记录本地代码中的日志消息?printf、fprintf、puts?...您是否可以重写代码,更改日志记录功能? - Jean-Philippe Pellet
由于涉及JNI:解决方案需要多可移植?它至少应在哪些平台上工作? - A.H.
3个回答

1
你可以尝试使用freopen来在本地端以和Java一样的方式重定向stdout,但问题在于如果你在自己的插件中使用它(带有一个新的JNI dll),这是否会起作用:它可能需要从执行控制台输出的dll内部使用。我不知道跨DLL之间流的交互情况。如果stdout是整个进程共享的流,则可能会起作用。

0

实际上你做不到。原生的DLL使用了stdio方法,而这些方法是Java无法访问的。如果你写入System.out,Java运行时最终会使用相同的方法,但由于明显的原因,对System.out的更改对底层的C运行时没有影响。

有一个硬件解决方案:获取第二个显示器,这样你就可以一直看到启动Eclipse的终端。


0

例如,Eclipse 2019-06定期将std::printf(...)std::cout从JNI代码委托给控制台视图。

刷新(实际打印)由fflush(stdout);完成。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接