Проблемы с Console.SetOut в режиме выпуска?

У меня есть куча Console.WriteLines в моем коде, который я могу наблюдать во время выполнения. Я общаюсь с родной библиотекой, которую я также написал.

Я хотел бы вставить некоторый printf в родную библиотеку и наблюдать за ними. Однако я не вижу их во время выполнения.

Я создал запутанное приложение hello world, чтобы продемонстрировать свою проблему. Когда приложение запускается, я могу отлаживаться в родной библиотеке и видеть, что вызван мир приветствия. Однако выход никогда не приземляется в текстовом редакторе. Обратите внимание: если один и тот же код запускается как консольное приложение, все работает нормально.

С#:

    [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();
    }

и нативная часть:

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

Обновление: hamishmcn ниже начал говорить о сборке отладки/выпуска. Я удалил собственный вызов в вышеуказанном методе button1_click и просто заменил его стандартным вызовом Console.WriteLine.net. Когда я компилировал и запускал это в режиме отладки, сообщения перенаправлялись в выходной файл. Когда я переключился в режим выпуска, но вызовы не были перенаправлены. Перенаправление консоли работает только в режиме отладки. Как мне обойти это?

Ответы

Ответ 1

Перенаправление консоли работает только в режиме отладки.

Ответ 2

Возможно, ваша родная библиотека по какой-то причине не знает о консоли.
Вы можете попробовать вызвать GetConsole и посмотреть, возвращается ли дескриптор. Если нет, вы можете попробовать выделить свою консоль, чтобы узнать, работает ли это.
Удачи!:-)


Обновление:
Я также написал пример приложения (консольное приложение С#, вызывающее родную С++ dll), и на консоли появляются как С# Console.WriteLine, так и собственный printf... Итак, что нам не хватает?
Вы всегда запускаете его в режиме отладки - вы вообще видите консольное окно, если вы запускаете его в режиме выпуска?

Обновление 2:
Извините, я должен сказать, что я вижу текст на консоли, но если я установил вывод Console в StreamWriter, как в вашем примере, тогда только текст WriteConsole перейдет в выходной файл, а printf по-прежнему экран

Ответ 3

В настоящее время у меня нет проекта, который я мог бы попробовать, но я бы определенно подозревал буферизацию. stdout буферизуется, если моя память служит мне правильной. Он очищает буфер каждый раз, когда он попадает в конец строки:

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

Или вы можете использовать fflush для очистки stdout:

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

Вы также можете отключить буферизацию с помощью setbuf:

setbuf(stdout, NULL);

Ответ 4

Внесите свой собственный printf (поверх vsnprintf, чтобы позаботиться о грязных деталях), который записывает на консоль:

#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;
}