WinCE中将调试信息写入文件的方法

来源:互联网 发布:saber仿真软件使用 编辑:程序博客网 时间:2024/05/22 16:02

相信做WinCE开发的朋友都会经常用串口将自己的调试信息打印输出,用来跟踪程序的运行情况,但在有的时候如果机器没有调试串口,我们可以将这些信息写入文本文件中,方便出现Bug后进行代码的跟踪,现将自己写的一段代码发上来与大家分享,希望大家多提建议。

代码中用一个宏,就可以方便的控制调试信息是写文件还是打印输入到调试串口,其中写文件部分给出了两种方法,一种是利用Win32 API的方式写文件,令一种是利用C语言的函数写文件,封装后用起来我觉得还是挺方便的,就跟使用printf/wprintf函数差不多,废话少说,下面直接贴上源代码。

/*************************************************************************************************
** 文件名称:  WriteDebugLog.h
** 摘     要: 用于处理调试时的Debug信息,通过宏WRITELOG_METHOD的不同取值来控制Debug信息的输出方式
**             WRITELOG_METHOD = 0,用于程序发布后关闭所有的调试信息;
**             WRITELOG_METHOD = 1,利用Win32 API函数将调试信息写入文件,在没有调试串口的时候可以取该值;
**             WRITELOG_METHOD = 2,利用C语言相关函数将调试信息写入文件,在没有调试串口的时候可以取该值;
**             WRITELOG_METHOD = 3,在有调试串口的情况下取该值,可以将调试信息从串口中打印输出。
** 用     法: 直接使用LOG或WLOG宏就可以实现所有功能,用法类似printf/wprintf函数。
*************************************************************************************************/

#ifndef __WRITE_DEBUG_LOG_H__
#define __WRITE_DEBUG_LOG_H__

void WriteDebugLog(const char *format,...);
void _TWriteDebugLog(const wchar_t *format,...);

#define WRITE_SYSTIME 1//1表示会写入系统时间,0表示不写入
#define WRITELOG_METHOD 0//写Debug文件的方法,0表示不做任何操作,1是用win32 API写文件,2是用C语言写文件,3表示用printf函数打印信息

#if (WRITELOG_METHOD == 1)
   #define STORAGE_ROOT_PATH   TEXT("\\Storage Card\\log.txt")
#elif (WRITELOG_METHOD == 2)
   #define STORAGE_ROOT_PATH   ("\\Storage Card\\log.txt")
#endif

#if (WRITELOG_METHOD == 3)
   #define LOG  printf
   #define WLOG wprintf
#elif (WRITELOG_METHOD != 3)
   #define LOG  WriteDebugLog
   #define WLOG _TWriteDebugLog
#endif

#endif /*__WRITE_DEBUG_LOG_H__*/

/*************************************************************************************************
** 文件名称:  WriteDebugLog.cpp

** 摘     要: 用于处理调试时的Debug信息,通过宏WRITELOG_METHOD的不同取值来控制Debug信息的输出方式
**             WRITELOG_METHOD = 0,用于程序发布后关闭所有的调试信息;
**             WRITELOG_METHOD = 1,利用Win32 API函数将调试信息写入文件,在没有调试串口的时候可以取该值;
**             WRITELOG_METHOD = 2,利用C语言相关函数将调试信息写入文件,在没有调试串口的时候可以取该值;
**             WRITELOG_METHOD = 3,在有调试串口的情况下取该值,可以将调试信息从串口中打印输出。
** 用     法: 直接使用LOG或WLOG宏就可以实现所有功能,用法类似printf/wprintf函数。
*************************************************************************************************/

#include "stdafx.h"
#include <windows.h>
#include "WriteDebugLog.h"

HANDLE ghLogFile = NULL;

FILE *fp = NULL;

int _tmain(int argc, _TCHAR* argv[])
{
 LOG("%d\r\n", 123456);
 WLOG(L"%d\r\n", 654321);
 return 0;
}

#if (WRITELOG_METHOD == 0)// WRITELOG_METHOD为0表示不做任何操作
void WriteDebugLog(const char *format,...)
{
 return;
}

void _TWriteDebugLog(const wchar_t *format,...)
{
 return;
}

#elif (WRITELOG_METHOD == 1) // WRITELOG_METHOD为1表示用win 32 API的方法来写文件
void WriteDebugLog(const char *format,...)
{
 va_list vl;
    static char sTempWriteBuf[1000];
    static char sWriteBuf[1024];
 memset(sTempWriteBuf, 0, 1000*sizeof(char));
 memset(sWriteBuf, 0, 1024*sizeof(char));
    DWORD loglen = 0;
 SYSTEMTIME time;
 ZeroMemory(&time, sizeof(time));
    static HANDLE h_sema = NULL;

    if (h_sema == NULL)
    {
        h_sema = CreateSemaphore(NULL, 1, 1, NULL);
    }

    WaitForSingleObject(h_sema, INFINITE);
    va_start(vl, format);
    vsprintf(sTempWriteBuf, format, vl);
    va_end(vl);

    if (ghLogFile == NULL)
    {
        ghLogFile = CreateFile((LPCWSTR)STORAGE_ROOT_PATH,
            GENERIC_READ | GENERIC_WRITE,
            FILE_SHARE_READ | FILE_SHARE_WRITE,
            NULL,
            OPEN_ALWAYS,
            FILE_ATTRIBUTE_NORMAL,
            NULL);
    }
 SetFilePointer(ghLogFile, 0, NULL, FILE_END);
   
#if (WRITE_SYSTIME == 1)
 GetLocalTime(&time);
 sprintf(sWriteBuf, "%.2d:%.2d:%.2d===>%s", time.wHour, time.wMinute, time.wSecond, sTempWriteBuf);
 WriteFile(ghLogFile, sWriteBuf, strlen(sWriteBuf), &loglen, NULL);
#elif (WRITE_SYSTIME == 0)
 sprintf(sWriteBuf, "%s", sTempWriteBuf);
 WriteFile(ghLogFile, sWriteBuf, strlen(sWriteBuf), &loglen, NULL);
#endif

  FlushFileBuffers(ghLogFile);

 //CloseHandle(ghLogFile);
 //ghLogFile = NULL;
    ReleaseSemaphore(h_sema, 1, 0);
}

void _TWriteDebugLog(const wchar_t *format,...)
{
 va_list vl;
    static wchar_t sTempWriteBuf[1000];
    static wchar_t sWriteBuf[1024];
 memset(sTempWriteBuf, 0, 1000*sizeof(wchar_t));
 memset(sWriteBuf, 0, 1024*sizeof(wchar_t));
    DWORD loglen = 0;
 SYSTEMTIME time;
 ZeroMemory(&time, sizeof(time));
    static HANDLE h_sema = NULL;

    if (h_sema == NULL)
    {
        h_sema = CreateSemaphore(NULL, 1, 1, NULL);
    }

    WaitForSingleObject(h_sema, INFINITE);
    va_start(vl, format);
    vswprintf(sTempWriteBuf, format, vl);
    va_end(vl);

    if (ghLogFile == NULL)
    {
        ghLogFile = CreateFile((LPCWSTR)STORAGE_ROOT_PATH,
            GENERIC_READ | GENERIC_WRITE,
            FILE_SHARE_READ | FILE_SHARE_WRITE,
            NULL,
            OPEN_ALWAYS,
            FILE_ATTRIBUTE_NORMAL,
            NULL);
    }
 SetFilePointer(ghLogFile, 0, NULL, FILE_END);

#if (WRITE_SYSTIME == 1)
 GetLocalTime(&time);
 swprintf(sWriteBuf, L"%.2d:%.2d:%.2d===>%s", time.wHour, time.wMinute, time.wSecond, sTempWriteBuf);
 int len = wcslen(sWriteBuf);
 char *chWriteBuf = new char[2*len + 1];
 memset(chWriteBuf, 0, 2*len + 1);
 WideCharToMultiByte(CP_ACP, 0, sWriteBuf, len, chWriteBuf, 2*len, NULL, NULL);
 chWriteBuf[2*len] = 0;
 WriteFile(ghLogFile, chWriteBuf, strlen(chWriteBuf), &loglen, NULL);
 delete []chWriteBuf;
#elif (WRITE_SYSTIME == 0)
 swprintf(sWriteBuf, L"%s", sTempWriteBuf);
 int len = wcslen(sWriteBuf);
 char *chWriteBuf = new char[2*len + 1];
 memset(chWriteBuf, 0, 2*len + 1);
 WideCharToMultiByte(CP_ACP, 0, sWriteBuf, len, chWriteBuf, 2*len, NULL, NULL);
 chWriteBuf[2*len] = 0;
 WriteFile(ghLogFile, chWriteBuf, strlen(chWriteBuf), &loglen, NULL);
 delete []chWriteBuf;
#endif

 FlushFileBuffers(ghLogFile);
 //CloseHandle(ghLogFile);
 //ghLogFile = NULL;
    ReleaseSemaphore(h_sema, 1, 0);
}

#elif (WRITELOG_METHOD == 2)// WRITELOG_METHOD为2表示用C语言的方法来写文件
void WriteDebugLog(const char *format,...)
{

if (NULL == fp)

{
  fp = fopen(STORAGE_ROOT_PATH, "a+");

}
 if (NULL == fp)
 {
  fp = NULL;
  return;
 }
 SYSTEMTIME time;
 ZeroMemory(&time, sizeof(time));

 va_list arg_ptr;

#if (WRITE_SYSTIME == 1)
 static char cTimeBuf[20];
 memset(cTimeBuf, 0, 20*sizeof(char));
 GetLocalTime(&time);
 sprintf(cTimeBuf, "%.2d:%.2d:%.2d===>", time.wHour, time.wMinute, time.wSecond);
 va_start(arg_ptr, cTimeBuf);
 vfprintf(fp, cTimeBuf, arg_ptr);
 va_end(arg_ptr);
#elif (WRITE_SYSTIME == 0)
#endif
 va_start(arg_ptr, format);
 vfprintf(fp, format, arg_ptr);
 va_end(arg_ptr);

 fclose(fp);

fp = NULL;
}

void _TWriteDebugLog(const wchar_t *format,...)
{

if (NULL == fp)

{
  fp = fopen(STORAGE_ROOT_PATH, "a+");

}

 if (NULL == fp)
 {
  fp = NULL;
  return;
 }
 SYSTEMTIME time;
 ZeroMemory(&time, sizeof(time));

 va_list arg_ptr;

#if (WRITE_SYSTIME == 1)
 char cTimeBuf[20];
 memset(cTimeBuf, 0, 20*sizeof(char));
 GetLocalTime(&time);
 sprintf(cTimeBuf, "%.2d:%.2d:%.2d===>", time.wHour, time.wMinute, time.wSecond);
 va_start(arg_ptr, cTimeBuf);
 vfprintf(fp, cTimeBuf, arg_ptr);
 va_end(arg_ptr);
#elif (WRITE_SYSTIME == 0)
#endif
 va_start(arg_ptr, format);
 vfwprintf(fp, format, arg_ptr);
 va_end(arg_ptr);

 fclose(fp);

fp = NULL;
}

#endif