4

I have a dll file that writes to STDOUT via std::cout.

Is there anyway to redirect the output from the dll to the application that is using it, without having to create functionality inside the dll? For example is there anyway to "listen" to its output?

I'm looking for an answer that will work cross-platform.

Soapy
  • 557
  • 14
  • 29
  • your question is not clear. do you want to see the print inside the caller-application's console or actually make the dll write to other stream you provide? – David Haim Jan 29 '15 at 12:59
  • 2
    did you try [std::cout.rdbuf(mystringbuf.rdbuf())](http://www.cplusplus.com/reference/ios/ios/rdbuf/)? – BeyelerStudios Jan 29 '15 at 13:00
  • @user3613500 I want to see the print inside the callers application. For example the dll will be writing to `cout` regardless of what is listening to it(if anything is). A real world example I can think of is if you run a program in a linux terminal and the program writes to `STDOUT` then it will just print to the terminal, but you can redirect it to something else using `2>&1` – Soapy Jan 29 '15 at 13:04
  • @BeyelerStudios that looks like it would work, but the example uses the applications `STDOUT`, how would I get the `STDOUT` from a dll? – Soapy Jan 29 '15 at 13:05
  • 2
    Why didn't you **say** that it writes to `stdout`, and not to `std::cout`? – Deduplicator Jan 29 '15 at 13:06
  • @Deduplicator My question assumes that the `cout` is not set to any other stream as _By default, cout is synchronized with stdout_ [link](http://www.cplusplus.com/reference/iostream/cout/) – Soapy Jan 29 '15 at 13:10
  • Deduplicator is right: it makes a big difference, update your question, maybe even remove the `c++` tag and replace it with `c` – BeyelerStudios Jan 29 '15 at 13:11
  • @BeyelerStudios I've updated my question, but I'm keeping in the `c++` tag as I also want to use `std::cout` with it. – Soapy Jan 29 '15 at 13:14
  • On a unixoid, I would simply move the real `STDOUT` out of the way and get me a pipe-pair. Which makes reversing that possible. On a windows, I'm not quite sure. – Deduplicator Jan 29 '15 at 13:14

2 Answers2

4

A DLL is not a separate process but a dynamic library that's loaded into your application address space. That means, when the DLL calls printf or whatever output into the stdout/stderr handlers, will inherit the stdout/stderr handles or your running application and will behave indeed as you put printf inside your application. If you want to capture the output of what's called from a DLL, you need to run it from a proxy EXE, that calls your DLL function. In that way, you can just redirect the stdout/stderr pipes to your process and do whatever you want.

By the way, in my opinion, this would be a totally wrong approach. If you use a DLL, you should have some sort of return codes from its function and not relay on its output on stdout.

Leonardo Bernardini
  • 1,076
  • 13
  • 23
  • So a function to return a pointer to a `std::streambuf` object or a pointer to an `std::ostream` object for example? – Soapy Jan 29 '15 at 13:22
  • If you want to absolutely parse text output, you can simply pass in a stream or a buffer, and instead of using printf, put that data inside your buffer. May I ask what kind of information you're in need to process ? – Leonardo Bernardini Jan 29 '15 at 13:25
  • 3
    It will just be debugging information, eg error message, id, variable contents, function information. But its all formatted into text before its sent to the output. – Soapy Jan 29 '15 at 13:31
  • and why you need to reparse that into your application ? If you tell us what your application do we may suggest a different approach – Leonardo Bernardini Jan 29 '15 at 13:32
  • The dll has functionality to communicate with the server/database, if anything goes wrong in the dll it will throw and write to a trace (which outputs to `STDOUT`). For most applications I just need pass it along to an application using the dll if required. – Soapy Jan 29 '15 at 13:43
  • if you do not write the try/catch into the DLL but just throw the exception, you can catch back the exception in your main application...this is the way to go. – Leonardo Bernardini Jan 29 '15 at 14:02
2

Regarding the cross-platform requirement, forget about it. When you throw in windows with:

I will focus on windows, since I expect this stuff to be easier on Unix (just redirect the host application stdout/stderr).

First of all make sure that the same msvcrt is linked by the host application and the DLL. 'stdout' means different objects if you load different msvcrt instances (i.e. host app links debug msvcrt and DLL links release msvcrt).

The above link details the different methods you may want to use (and combine) depending on the DLL.