使用OutputDebugString输出调试信息,使用DebugWindow来捕获它

OutputDebugString API函数包括MultiChar和Unicode两种版本:OutputDebugStringA和OutputDebugStringW,原型:如下:

void
__stdcall
OutputDebugStringA(
    const char* lpOutputString
    );


void
__stdcall
OutputDebugStringW(
   const wchar_t lpOutputString
    );

使用起来非常简单,只有一个参数而且没有返回值.

 

DebugWindow的实现:

由2个事件,1个系统缓冲区的映射指针来实现.

1个事件用来得到对系统缓冲区的访问权,另一个用来通过对系统缓冲区操作完毕.

缓冲区的声明为:

#pragma pack(push)
#pragma pack(1)
typedef struct __DEBUGBUFFER
{
 DWORD sz;
 char szString[4096 - sizeof(DWORD)]; //这里保存了OutputDebugString输出的字符串
} DEBUGBUFFER, *PDEBUGBUFFER;
#pragma pack(pop)

 

请求访问缓冲区的事件名为:"DBWIN_BUFFER_READY"

通知缓冲区有新数据的事件名为:"DBWIN_DATA_READY"
系统缓冲区对象名为:"DBWIN_BUFFER"

 

实例代码:

// DebugOutCapture.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#pragma pack(push)
#pragma pack(1)
typedef struct __DEBUGBUFFER
{
 DWORD sz;
 char szString[4096 - sizeof(DWORD)];
} DEBUGBUFFER, *PDEBUGBUFFER;
#pragma pack(pop)
;
#define MAX_DEBUG_BUF_LEN (4096)
#define _Try __try
#define _Finally __finally

int _tmain(int argc, _TCHAR* argv[])
{
 HANDLE m_hReadyEvent;
 DWORD m_dwResult;
 HANDLE hMapping = NULL;
 HANDLE hAckEvent = NULL;
 PDEBUGBUFFER pdbBuffer = NULL;
 //TCHAR tzBuffer[MAX_DEBUG_BUF_LEN];
 _Try
 {
#define _LeaveIf(expr) if(expr == TRUE) /
      return FALSE;
  // 设置初始结果
  m_dwResult = ERROR_INVALID_HANDLE;
  // 打开事件句柄
  hAckEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("DBWIN_BUFFER_READY"));
  _LeaveIf(hAckEvent == NULL);
  m_hReadyEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("DBWIN_DATA_READY"));
  _LeaveIf(m_hReadyEvent == NULL);
  // 创建文件映射
  hMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, MAX_DEBUG_BUF_LEN, TEXT("DBWIN_BUFFER"));
  _LeaveIf(hMapping == NULL);
  // 映射调试缓冲区
  pdbBuffer = (PDEBUGBUFFER) MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
  _LeaveIf(pdbBuffer == NULL);
  // 循环
  for (m_dwResult = ERROR_SIGNAL_PENDING; (m_dwResult == ERROR_SIGNAL_PENDING); )
  {
   // 等待缓冲区数据
   SetEvent(hAckEvent);
   if (WaitForSingleObject(m_hReadyEvent, INFINITE) == WAIT_OBJECT_0)
   {
    // 如果是继续等待,否则表示主线程发出了停止信号,退出当前线程
    if (m_dwResult == ERROR_SIGNAL_PENDING)
    {
     // 添加新项
     printf(pdbBuffer->szString);
    }
   }
   else
   {
    // 等待失败
    m_dwResult = WAIT_ABANDONED;
   }
  }
 }
 _Finally
 {
#define _SafeCloseHandle(handle) if(handle != NULL) /
          CloseHandle(handle);
  // 释放
  if (pdbBuffer)
  {
   UnmapViewOfFile(pdbBuffer);
  }
  _SafeCloseHandle(hMapping);
  _SafeCloseHandle(m_hReadyEvent);
  _SafeCloseHandle(hAckEvent);
 
  // 返回结果
  return m_dwResult;
 }
}

 

一个非常典型的应用就是在VisualStudio之中IDE的输出子窗体,它其实就是一个Debug信息接收窗体,只需在源码中为OutputDebugString函数输入需要输出的调试信息就可以了,例子:

 

CString strDebugOutput;

strDebugOutput.Format("This is debug infor/n");

OutputDebugString(strDebugOutput.GetBuffer());

 

运行就可以看到在输出窗体中的Debug信息输出.

 

实例和测试工程请从这里下载:

http://download.csdn.net/source/940777

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值