Re: Redirect stdout from unmanaged DLL
- From: "William DePalo [MVP VC++]" <willd.no.spam@xxxxxxxx>
- Date: Thu, 23 Jun 2005 15:16:02 -0400
"Thomas W. Brown" <thomas_w_brown@xxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:51BDF38C-9127-4B12-B254-1CCF3DDFC7D9@xxxxxxxxxxxxxxxx
> I don't think this will work in my case -- I've been scratching my head to
> try and figure out; 1) how I can do this from my managed code layer, and
> 2)
> even if I could, what to I supply as the low-level device handle that
> corresponds to my TextWriter that I use for the redirection.
Well, what I posted is a way to "wire" a "file" known to the C/C++ runtime
to an operating system handle. If you could have communicated the Win32
handle of the file to which you redirected your console, then my little hack
would have done the job.
> (1) is necessary because I do not have the ability to alter the unmanaged
> DLLs -- they are black boxes for me.
OK. There is almost always more than one way to skin a cat. The little C#
hack below does three things:
1) it points the Console at a file
2) it redirects the standard output device of the application to that file
using a bit of interop
3) it calls a function exported from DLL written in C++ which uses the plain
vanilla I/O stream for output
//--------------------------------------------------------------------------------------------------------------
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace Redirect
{
class Class1
{
[ DllImport("Kernel32.dll", SetLastError = true) ]
public static extern int SetStdHandle(int device, IntPtr handle);
[ DllImport("SayHello.dll") ]
public static extern void SayHello();
[STAThread]
static void Main(string[] args)
{
int status;
IntPtr handle;
FileStream fs;
StreamWriter sw;
fs = new FileStream("console.txt", FileMode.Create);
sw = new StreamWriter(fs);
sw.AutoFlush = true;
Console.SetOut(sw);
Console.WriteLine("This is a test of output via C#.");
handle = fs.Handle;
status = SetStdHandle(-11, handle);
SayHello();
}
}
}
//--------------------------------------------------------------------------------------------------------------
This is the source to the DLL I used to test the redirection:
//--------------------------------------------------------------------------------------------------------------
#include <windows.h>
#include <iostream>
void WINAPI SayHello()
{
std::cout << "This is a test of output in C++" << std::endl;
}
//--------------------------------------------------------------------------------------------------------------
Both lines were written to the file. That should do you, right?
> Thanks, though,
You are welcome.
Note that I/O is complicated. If the DLL had chosen to use the Win32 API
function WriteConsole() instead of the C++ I/O stream then it's I/O wouldn't
have been written to the file (at least I don't think so but I am frankly
too lazy and too busy now to test that).
Further if the call to SetStdHandle() does not precede the load of a DLL
whose output you want to capture then it will go to the real console instead
of the file.
Finally, the mysterious looking number -11 in the C# source is the manifest
constant STD_OUTPUT_HANDLE defined in <winbase.h>. I don't do enough interop
to know if there are .Net equivalents of such things. If there is one, I'm
all ears. :-)
Regards,
Will
.
- Follow-Ups:
- Re: Redirect stdout from unmanaged DLL
- From: Thomas W. Brown
- Re: Redirect stdout from unmanaged DLL
- References:
- Redirect stdout from unmanaged DLL
- From: Thomas W. Brown
- Re: Redirect stdout from unmanaged DLL
- From: William DePalo [MVP VC++]
- Re: Redirect stdout from unmanaged DLL
- From: Thomas W. Brown
- Redirect stdout from unmanaged DLL
- Prev by Date: RE: passing string array to C++
- Next by Date: Re: Redirect stdout from unmanaged DLL
- Previous by thread: Re: Redirect stdout from unmanaged DLL
- Next by thread: Re: Redirect stdout from unmanaged DLL
- Index(es):
Relevant Pages
|