14

i have a bunch of Console.WriteLines in my code that I can observe at runtime. I communicate with a native library that I also wrote.

I'd like to stick some printf's in the native library and observe them too. I don't see them at runtime however.

I've created a convoluted hello world app to demonstrate my problem. When the app runs, I can debug into the native library and see that the hello world is called. The output never lands in the textwriter though. Note that if the same code is run as a console app then everything works fine.

C#:

    [DllImport("native.dll")]
    static extern void Test();

    StreamWriter writer;

    public Form1()
    {
        InitializeComponent();

        writer = new StreamWriter(@"c:\output.txt");
        writer.AutoFlush = true;
        System.Console.SetOut(writer);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Test();
    }

and the native part:

__declspec(dllexport) void Test()
{
    printf("Hello World");
}

Update: hamishmcn below started talking about debug/release builds. I removed the native call in the above button1_click method and just replaced it with a standard Console.WriteLine .net call. When I compiled and ran this in debug mode the messages were redirected to the output file. When I switched to release mode however the calls weren't redirected. Console redirection only seems to work in debug mode. How do I get around this?

Matt Jacobsen
  • 5,814
  • 4
  • 35
  • 49
  • No answer, but this post http://stackoverflow.com/questions/2570001/allow-native-dll-to-output-stdout-stderr-in-c-console-application suggests it should work fine. Hmm. It sounds like stdout is redirecting somewhere else; either that or it's being buffered. – Steven Mackenzie Apr 15 '10 at 15:49
  • 1
    How are you launching/attaching to the native library? – chilltemp Apr 15 '10 at 21:16
  • I've attached to the process via vs.net and also just let it run on the console, and I don't see anything from the native stdout. I've also tried DbgView which also doesn't output anything native, only my .net messages. – Matt Jacobsen Apr 16 '10 at 07:54
  • 1
    But how exactly does your code work? Is it .Net console application that uses PInvoke to call native library? – CodeRipper Apr 16 '10 at 13:46
  • it's a huge WindowsForms application, but we enable console/debug output to a window for debugging purposes - I can see all Console.WriteLine and Debug.WriteLine messages here. The native library is called through PInvoke. – Matt Jacobsen Apr 19 '10 at 08:52
  • +1 to `C makes me love C# more` :) – abatishchev Apr 19 '10 at 09:11

4 Answers4

2

Perhaps your native library, for some reason, doesn't know about the console.
You could try calling GetConsole an see if a handle is returned. If not you could try allocating your own console to see if that works.
Good luck! :-)


Update:
I wrote a sample app too (console C# app calling native C++ dll) and both the C# Console.WriteLine and the native printf appear on the console... So what are we missing?
Do you always run it in debug mode - do you see a console window at all if you run it in release mode?
Update 2:
Sorry, I should say I see the text on the console, but if I set the Console output to a StreamWriter, like you have in your example, then only the WriteConsole text goes to the output file, the printfs still go to the screen

hamishmcn
  • 7,843
  • 10
  • 41
  • 46
  • See also http://stackoverflow.com/questions/432832/what-is-the-different-between-api-functions-allocconsole-and-attachconsole-1 – abatishchev Apr 19 '10 at 09:10
  • abatishchev: that's yet another random function call. Don't mean to be funny, but what is really wrong with my simple printf calls in the first place? – Matt Jacobsen Apr 19 '10 at 09:13
  • interesting, did you try AllocConsole(), to see if it worked then? – hamishmcn Apr 19 '10 at 09:52
  • no, I called GetStdHandle, which returned a valid handle to a console. As I understand it, I don't need to call AllocConsole – Matt Jacobsen Apr 19 '10 at 09:56
  • I'm confusing things now. Let me try to clarify: Based on your suggestion I veered off on a tangent and tried GetStdHandle, which returned a valid handle to standard output. The c component of my program is really just a library - there's no console window for it & so AllocConsole/WriteConsole won't help. That shouldn't stop it being able to write to stdout via printf's or whatever though. – Matt Jacobsen Apr 19 '10 at 10:04
  • Which means, that trying for WriteConsole is of no use :) – Matt Jacobsen Apr 19 '10 at 10:49
  • I wrote a sample app too (console C# app calling native C++ dll) and both the C# Console.WriteLine and the native printf appear on the console... So what are we missing?... Do you always run it in debug mode - do you see a console window at all if you run it in release mode? – hamishmcn Apr 19 '10 at 22:11
  • I always run the native library in release mode, the reason being that a debug release of a native library never runs on a non-dev machine. – Matt Jacobsen Apr 20 '10 at 07:09
1

I don't currently have any project I could try this on but I would definitely suspect buffering. stdout is buffered if my memory serves me right. It flushes buffer every time it hits the end of line:

printf("Should be flushed immediatelly\n");

Or you can use fflush to flush the stdout:

printf("Will be buffered and then flushed");
fflush(stdout);

You can also turn buffering off by using setbuf:

setbuf(stdout, NULL);
CodeRipper
  • 302
  • 2
  • 7
1

Console redirection only works in debug mode.

Matt Jacobsen
  • 5,814
  • 4
  • 35
  • 49
0

Implement your own printf (on top of vsnprintf to take care of the dirty details) that writes to the console:

#include <stdarg.h>

int printf(const char *fmt, ...)
{
    char buffer[LARGESIZE];
    int rv;
    va_list ap;
    va_start(ap, fmt);
    rv = vsnprintf(buffer, sizeof(buffer), fmt, ap);
    va_end(ap);

    Console.WriteLine(buffer);

    return rv;
}
R Samuel Klatchko
  • 74,869
  • 16
  • 134
  • 187