我有一个用C开发的大程序,大多数函数有几个
fprintf(stderr, "message")
行。
但是现在我需要在Java程序中使用这些函数。所以,我实现了一个JNI接口,用于在Java和C之间进行通信。一切正常,Java和C可以进行通信,但现在我想在Java中捕获几个C的stderr ...我该怎么做?
干杯;)
答案 0 :(得分:1)
根据我对同样问题的经验,我可以说JNI桥对于通过标准流输出JNI的重要性有非常奇怪的看法。通常它会进行大量缓存,溢出不可预测的块和时间,我们也没有弄清楚如何强制冲洗。
我们最终将*printf()
语句的大规模正则表达式替换为记录到文件,在C端完成。抛出生成的日志文件比任何试图说服JVM在C层都这么说时真正需要日志记录的尝试更可靠,而不是当JVM把它放在缓冲区时。
答案 1 :(得分:0)
当您调用JNI库时,您将其加载到JVM进程中,因此库STDOUT和STDERR将是JVM STDOUT和STDERR。所以问题是特定于操作系统,更像是“一个进程如何读取自己的STDOUT / STDERR?”
有几种可能性Internally capture/redirect stdout?,但我看不到的只是阅读你的图书馆的STDOUT或STDERR(我认为通过我给你的例子,一旦你执行重定向你不能回去使用控制台输出(*))。
如评论所述,答案将主要取决于您的操作系统。
(*)我可能错了,我对C /系统编程不太熟练。
答案 2 :(得分:0)
根据this answer,我认为您应该能够重新分配processe's stderr。在JNI函数执行时,您将需要另一个从中读取的线程,以便它不会阻塞。
答案 3 :(得分:0)
可能的解决方法是执行以下操作:http://www.thecodingforums.com/threads/redirect-cout-and-cerr-to-system-out-and-system-err.635861/
我想出的解决方案是用两个创建一些JNI代码 方法:
- 将stdout重定向到管道的文件
- 将输出存储在那里的
然后fow是:
- 调用重定向的函数
- 进行多项其他JNI通话
- 获取输出并将其写入我想要的位置
上面链接提供的implementation就像这样
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <jni.h>
#include "Nat1.h"
#define MAXBUF 20480
static int oldstdout;
static int pipehandles[2];
static char buf[MAXBUF];
JNIEXPORT void JNICALL Java_Nat2_init(JNIEnv *cntx, jobject me)
{
oldstdout = _dup(_fileno(stdout));
_pipe(pipehandles,MAXBUF,_O_BINARY);
_dup2(pipehandles[1],_fileno(stdout));
}
JNIEXPORT jstring JNICALL Java_Nat2_done(JNIEnv *cntx, jobject me)
{
int n;
fflush(stdout);
_dup2(oldstdout,_fileno(stdout));
n = _read(pipehandles[0],buf,sizeof(buf));
buf[n] = '\0';
return (*cntx)->NewStringUTF(cntx,buf);
}
这有点麻烦,因为您需要启动捕获stderr,然后在您想要查看它时稍后获取它。