2017-07-13 6 views
1

JAVAからJNI経由でCコードを呼び出します。JNI printf to log4j

私のCでは、私はlog4jでログしたいと思います。

printf("Could not find HID device\n"); 
    fflush(stdout); 

彼らは私が私のロガーに標準出力をリダイレクトするのlog4jで、Eclipseのコンソールで正常に表示さ:私は「のSystem.out.println」を呼び出すと

 System.setOut(new PrintStream(new OutputStreamLogger(log, Priority.DEBUG), true)); 

、それは私のログファイルに書き込まれています。

しかし、JNIのprintfはそうではありません。 彼らはstdoutにいませんか?
どうすればログファイルに保存できますか?

+0

'System.setOut'は' System.out.println'が 'stdout'からカスタムストリームに向けて変更されます。実際には 'stdout'は変更されません。 – bradimus

+0

すべてのstdoutをキャプチャする方法はありますか? – Romain

答えて

0

あなたができることは、あなたのJNIコアの中にdupdup2を使用することです。これにより、標準出力をLog4Jで使用されているファイルに関連付けることができます。

int newStdout(const char *filename, fpos_t *pos) 
{ 
    fflush(stdout); 
    fgetpos(stdout, pos); 
    int fd = dup(fileno(stdout)); 
    freopen(filename, "w", stdout); 
    return fd; 
} 

void revertStdout(int fd, fpos_t *pos) 
{ 
    fflush(stdout); 
    dup2(fd, fileno(stdout)); 
    close(fd); 
    clearerr(stdout); 
    fsetpos(stdout, pos); 
} 

次に、あなたのコードでは、あなたがこのようにそれを使用することができます:

fpos_t pos; 
char filelocation[256] = "some_place"; 
int fd = newStdout(filelocation, &pos); 
// 
//... do some stuff here ... 
//... things that put data into stdout ... 
// 
revertStdout(fd, &pos); 

これは、あなたが探している正確にものではありませんが、それでも、あなたのための解決策になるかもしれません。

+0

アイデアありがとう – Romain

1

stdoutにあります。

問題は、System.setOut(new PrintStream(new OutputStreamLogger(log, Priority.DEBUG), true));は、stdoutの代わりにカスタムプリントストリームを使用するように指示しています。

問題は簡単な解決策がありません。

私が想像できる最も簡単なのはcJavaロガーを使用するコードを変更することです。

私はそれに住んでいるか、cロギングをセットアップし、2つのログファイルを用意することをお勧めします。はるかに簡単です。

+0

System.setOutは標準出力ストリームをカスタムプリントストリームに再割り当てします。 stdoutが新しいPrintStreamにリダイレクトされ、printfsがstdoutにある場合、それらはリダイレクトされないのはなぜですか?明示的な呼び出しだけをリダイレクトしますか? – Romain

+0

OSの観点からではありません。 'stdout'は値が' 1'のファイルハンドラAFAIRです。その呼び出しの後には何も起こりません。 – talex

+0

Eclipseコンソールはどのようにそれらを印刷できますか?もちろん、Cからログファイルを作成できますが、私は – Romain