首页 文章

控制台中的OutputDebugString()

提问于
浏览
4

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

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

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

1 回答

  • 2

    OutputDebugStringA 生成异常 DBG_PRINTEXCEPTION_C (win10中的 W 版本 - 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 的系统实现与here一样 - 它确实称为RaiseException,正是这个参数,仅在异常处理程序中而不是 MessageBox - 代码描述为here .

相关问题