2

I call some C code via JNI from JAVA.

In my C, I do multiple printf that I want to log with log4j.

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

They show up fine in the Eclipse console, with log4j I redirect the stdout to my logger :

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

When I call "System.out.println", it's written to my log file.

But the JNI printfs don't. Aren't they in the stdout ?
How can I put them in my logfile ?

Romain
  • 151
  • 1
  • 12

2 Answers2

1

They in stdout.

Problem is that System.setOut(new PrintStream(new OutputStreamLogger(log, Priority.DEBUG), true)); just instruct to use custom print stream instead of stdout.

You problem do not have simple solution.

Simplest that I can imagine is to change you c code to use Java logger.

I suggest you to live with it or setup c logging and have two log files. It will be much easier.

talex
  • 17,973
  • 3
  • 29
  • 66
  • System.setOut reassigns the standard output stream to my custom printstream. If the stdout is redirected to the new PrintStream, and the printfs are in the stdout, why aren't they redirected ? Does it redirect only explicit calls ? – Romain Jul 13 '17 at 14:17
  • Not from OS point of view. `stdout` is file handler with value `1` AFAIR. After that call nothing happens with it. – talex Jul 13 '17 at 14:19
  • How does Eclipse console manage to print them ? Of course I can create a log file from C but I would like to understand – Romain Jul 13 '17 at 14:23
  • 1
    You logger actually prints to OS `stdout` and Eclipse read those output. – talex Jul 13 '17 at 14:26
0

One thing you can do is to use dup and dup2 inside your JNI core. This way, you can associate your stdout with the file that is used by 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);
}

Then, in your code you can use it like this:

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);

This is not exactly what you are looking for, but still, might be a solution for you.

Oo.oO
  • 12,464
  • 3
  • 23
  • 45