控制台中的OutputDebugString()

时间:2017-01-04 14:17:12

标签: c++ c windows debugging outputdebugstring

我使用的是使用函数OutputDebugString()的第三方库,在阅读MSDN文档时,似乎表明这是用于打印到调试器。

但是在我的情况下这是不方便的,如果没有连接调试器,是否有办法读取此输出?

如果是我的LIB,我希望每当用户通过--debug或类似时输出都转到stdout / stderr,但是因为它不是我正在寻找其他方式来传递这个信息到连接控制台(或文件)而不连接调试器。

1 个答案:

答案 0 :(得分:3)

OutputDebugStringA在win10中生成异常DBG_PRINTEXCEPTION_CW版本 - DBG_PRINTEXCEPTION_WIDE_C),带有2个参数 - (字符串长度为字符+ 1,字符串指针) - 作为结果我们可以自己处理这个异常(此异常的系统默认处理程序执行this)。

OutputDebugString重定向到控制台的示例处理程序:

LONG NTAPI VexHandler(PEXCEPTION_POINTERS ExceptionInfo)
{
    PEXCEPTION_RECORD ExceptionRecord = ExceptionInfo->ExceptionRecord;

    switch (ExceptionRecord->ExceptionCode)
    {
    case DBG_PRINTEXCEPTION_WIDE_C:
    case DBG_PRINTEXCEPTION_C:

        if (ExceptionRecord->NumberParameters >= 2)
        {
            ULONG len = (ULONG)ExceptionRecord->ExceptionInformation[0];

            union {
                ULONG_PTR up;
                PCWSTR pwz;
                PCSTR psz;
            };

            up = ExceptionRecord->ExceptionInformation[1];

            HANDLE hOut = GetStdHandle(STD_ERROR_HANDLE);

            if (ExceptionRecord->ExceptionCode == DBG_PRINTEXCEPTION_C)
            {
                // localized text will be incorrect displayed, if used not CP_OEMCP encoding 
                // WriteConsoleA(hOut, psz, len, &len, 0);

                // assume CP_ACP encoding
                if (ULONG n = MultiByteToWideChar(CP_ACP, 0, psz, len, 0, 0))
                {
                    PWSTR wz = (PWSTR)alloca(n * sizeof(WCHAR));

                    if (len = MultiByteToWideChar(CP_ACP, 0, psz, len, wz, n))
                    {
                        pwz = wz;
                    }
                }
            }

            if (len)
            {
                WriteConsoleW(hOut, pwz, len - 1, &len, 0);
            }

        }
        return EXCEPTION_CONTINUE_EXECUTION;
    }

    return EXCEPTION_CONTINUE_SEARCH;
}

并设置此处理程序需要调用:

AddVectoredExceptionHandler(TRUE, VexHandler);

OutputDebugString的{​​{1}}的系统实现 - 它实际上只使用此参数调用here,仅在异常处理程序中MessageBox - 代码描述为RaiseException