views:

304

answers:

2

I have been trying to capture stdout and stderr output from a DLL compiled in MSVC++ that my Delphi app statically links to, but so far have been unsuccessful.

procedure Test;
var
  fs: TFileStream;

begin
  fs := TFileStream.Create('C:\temp\output.log', fmCreate or fmShareDenyWrite);
  SetStdHandle(STD_OUTPUT_HANDLE, fs.Handle);
  SetStdHandle(STD_ERROR_HANDLE, fs.Handle);

  dllFunc(0); // Writes to stdout in MSVC++ console app, but not here
  // fs.Length is always zero

  fs.Free;
end;

Thought I was on the right track, but it does not work.

  1. Is SetStdHandle() enough?
  2. Is TFileStream the right thing to use here?
  3. Am I using TFileStream properly for SetStdHandle()?
  4. Is it possible that the DLL sets its stdout/stderr handles when the app loads? If so, where is the best place to use SetStdHandle() or equivalent?

Any help would be appreciated.

A: 

If your app is a console app, you could just run the thing and capture everything to stdout with redirection. i.e.

C:\MyAppWhichCallsDll.exe > c:\temp\output.log
Chris Thornton
+7  A: 

If the DLL grabs the stdout handles when it is loaded, then you will need to dynamically load the DLL after you have changed the stdout handles in your code.

dthorpe
Definitely a good point, although even now that I load the DLL dynamically (after calling SetStdHandle), I still get no output.
Alan G.
dthorpe, your recommendation worked (I just was not seeing it). Thank you very much.
Alan G.