【问题标题】:JNI printf to log4jJNI printf 到 log4j
【发布时间】:2017-07-13 14:06:11
【问题描述】:

我通过 JNI 从 JAVA 调用一些 C 代码。

在我的 C 中,我做了多个 printf,我想用 log4j 记录。

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

它们在 Eclipse 控制台中显示良好,使用 log4j 我将标准输出重定向到我的记录器:

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

当我调用“System.out.println”时,它会写入我的日志文件。

但是 JNI printfs 没有。 他们不是在标准输出中吗?
我怎样才能把它们放在我的日志文件中?

【问题讨论】:

  • System.setOut 将指向 System.out.println 的位置从 stdout 更改为您的自定义流。它实际上并没有改变stdout
  • 有没有办法捕获所有的标准输出?

标签: java c java-native-interface printf stdout


【解决方案1】:

他们在stdout

问题是System.setOut(new PrintStream(new OutputStreamLogger(log, Priority.DEBUG), true)); 只是指示使用自定义打印流而不是stdout

你的问题没有简单的解决方案。

我能想象到的最简单的方法是将c 代码更改为使用Java 记录器。

我建议您使用它或设置c 日志记录并拥有两个日志文件。这会容易得多。

【讨论】:

  • System.setOut 将标准输出流重新分配给我的自定义打印流。如果 stdout 被重定向到新的 PrintStream,并且 printfs 在 stdout 中,为什么不重定向它们?它是否只重定向显式调用?
  • 不是从操作系统的角度来看。 stdout 是值为 1 AFAIR 的文件处理程序。在那次通话之后,它什么也没有发生。
  • Eclipse 控制台如何打印它们?当然,我可以从 C 创建一个日志文件,但我想了解
  • 您的记录器实际上打印到 OS stdout 和 Eclipse 读取这些输出。
【解决方案2】:

您可以做的一件事是在您的 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);

这不是您正在寻找的,但仍然可能是您的解决方案。

【讨论】:

  • 感谢您的想法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-07
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 2011-07-13
  • 2019-02-05
相关资源
最近更新 更多